Advertisement
Guest User

Untitled

a guest
Dec 26th, 2021
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.29 KB | None | 0 0
  1. template <typename node, typename update>
  2. struct segTree{
  3. ll len;
  4. vector<node> t;
  5. vector<update> u;
  6. vector<bool> lazy;
  7. vector<ll> tl,tr;
  8. node identity_element;
  9. update identity_transformation;
  10.  
  11. template<typename T>
  12. segTree(T &a){
  13. len = a.size();
  14. t.resize(4 * len);
  15. u.resize(4 * len);
  16. lazy.resize(4 * len);
  17. tl.resize(4 * len);
  18. tr.resize(4 * len);
  19. identity_element = node();
  20. identity_transformation = update();
  21. build(a,1,0,len-1);
  22. }
  23.  
  24. template <typename T>
  25. void build(const T &a, const ll &v, const ll &l, const ll &r){
  26. tl[v]=l;
  27. tr[v]=r;
  28. if (l == r){
  29. t[v]=a[l];
  30. return;
  31. }
  32. ll tm = (l + r) >> 1;
  33. build(a, v << 1, l, tm);
  34. build(a, v << 1 | 1, tm + 1, r);
  35. t[v].merge(t[v << 1], t[v << 1 | 1]);
  36. }
  37.  
  38. void apply(const ll &v, update val){
  39. if (tl[v] != tr[v]){
  40. lazy[v] = 1;
  41. u[v].combine(val, tl[v], tr[v]);
  42. }
  43. val.apply(t[v], tl[v], tr[v]);
  44. }
  45.  
  46. void pushdown(const ll &v){
  47. if(lazy[v]){
  48. apply(v << 1, u[v]);
  49. apply(v << 1 | 1, u[v]);
  50. u[v] = identity_transformation;
  51. lazy[v] = 0;
  52. }
  53. }
  54.  
  55. // rupd = range update
  56. void rupd(const ll &v,const ll &l, const ll &r, update val){
  57. if (l > tr[v] || r < tl[v])
  58. return;
  59. if (tl[v] >= l && tr[v] <= r){
  60. apply(v,val);
  61. return;
  62. }
  63. pushdown(v);
  64. rupd(v << 1, l, r, val);
  65. rupd(v << 1 | 1, l, r, val);
  66. t[v].merge(t[v << 1], t[v << 1 | 1]);
  67. }
  68.  
  69. node query(const ll &v,const ll &l, const ll &r){
  70. if (l > tr[v] || r < tl[v])
  71. return identity_element;
  72. if (tl[v] >= l && tr[v] <= r)
  73. return t[v];
  74. pushdown(v);
  75. node a,b,ans;
  76. a=query(v*2,l,r);
  77. b=query(v*2+1,l,r);
  78. ans.merge(a,b);
  79. return ans;
  80. }
  81.  
  82. template<typename T>
  83. ll descent_right(ll l, T x, ll v, node &prev) {
  84. if (l > tr[v]) // node is completely out of range
  85. return len;
  86. if(l <= tl[v]){ // node is completely in range
  87. node cur;
  88. cur.merge(prev,t[v]);
  89. if (!cur.check(x)){ // go further right than this node
  90. swap(prev,cur); // merging this node's contribution
  91. return len;
  92. }
  93. if (tl[v]==tr[v]) {
  94. return tr[v];
  95. }
  96. }
  97. pushdown(v);
  98. ll ans=descent_right(l, x, v*2, prev); // trying to find in left child
  99. if(ans!=len)return ans; // found in left child
  100. return descent_right(l, x, v*2+1, prev); // finding in right child
  101. }
  102. template<typename T>
  103. ll descent_left(ll r, T x, ll v, node &prev) {
  104. if (r < tl[v]) // node is completely out of range
  105. return -1;
  106. if(r >= tr[v]){ // node is completely in range
  107. node cur;
  108. cur.merge(t[v],prev);
  109. if (!cur.check(x)){ // go further left than this node
  110. swap(cur,prev); // merging this node's contribution
  111. return -1;
  112. }
  113. if (tl[v]==tr[v]) {
  114. return tl[v];
  115. }
  116. }
  117. pushdown(v);
  118. ll ans=descent_left(r, x, v*2+1, prev); // trying to find in right child
  119. if(ans!=-1)return ans; // found in right child
  120. return descent_left(r, x, v*2, prev); // finding in left child
  121. }
  122.  
  123. template<typename T>
  124. ll descent_right(ll l, T x){ // minimum r such that [l...r].check(x) == true, returns segtree.leng if not found
  125. node prev=node();
  126. return descent_right(l,x,1,prev);
  127. }
  128. template<typename T>
  129. ll descent_left(ll r, T x){ // maximum l such that [l...r].check(x) == true, returns -1 if not found
  130. node prev=node();
  131. return descent_left(r,x,1,prev);
  132. }
  133. node query(const ll &l, const ll &r){
  134. return query(1, l, r);
  135. }
  136. void rupd(const ll &l, const ll &r, update upd){
  137. rupd(1, l, r, upd);
  138. }
  139. };
  140.  
  141. struct node1{
  142. ll sum=0;
  143. // use more variables if you want more information
  144. // these default values should be identity_element
  145.  
  146. node1() {}
  147. node1(ll val){
  148. sum=val;
  149. }
  150. void merge(const node1 &l, const node1 &r){
  151. sum=l.sum+r.sum;
  152. }
  153. bool check(ll x){
  154. return false;
  155. }
  156. };
  157.  
  158. struct update1{
  159. ll v=0;
  160. ll pending=0;
  161. // use more variables if you want more information
  162. // these default values should be identity_transformation
  163.  
  164. update1() {}
  165. update1(ll val){
  166. v=val;
  167. pending++;
  168. }
  169. // combine the current update1 with the other update1
  170. void combine(update1 &other, const ll &tl, const ll &tr){
  171. if((pending+other.pending)&1) pending=1;
  172. else pending=0;
  173. }
  174. // store the correct information in the node1 x
  175. void apply(node1 &x, const ll &tl, const ll &tr){
  176. if(pending){
  177. x.sum=(tr-tl+1)-x.sum;
  178. pending=0;
  179. }
  180. }
  181. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement