demoralizer69

Untitled

Jul 1st, 2020
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.72 KB | None | 0 0
  1. const int32_t maxn=2e5+5;
  2. template<typename NODE,typename UPDATE>
  3. struct segtree{
  4.     bool built=false,lazy[4*maxn];
  5.     NODE zero=NODE(),t[4*maxn];
  6.     UPDATE noop=UPDATE(),upds[4*maxn];
  7.     int32_t tl[4*maxn],tr[4*maxn];
  8.     inline void pushdown(int32_t v)
  9.     {
  10.         if(lazy[v]){
  11.             apply(v*2,upds[v]);
  12.             apply(v*2+1,upds[v]);
  13.             lazy[v]=0;
  14.             upds[v]=noop;
  15.         }
  16.     }
  17.     inline void apply(int32_t v,UPDATE &val)
  18.     {
  19.         if(tl[v]!=tr[v]){
  20.             lazy[v]=1;
  21.             upds[v].combine(val,tl[v],tr[v]);
  22.         }
  23.         val.apply(t[v],tl[v],tr[v]);
  24.     }
  25.     template<typename T>
  26.     void build(T a, int32_t v, int32_t l, int32_t r) {
  27.         tl[v]=l;
  28.         tr[v]=r;
  29.         if (l == r) {
  30.             t[v]=a[l];
  31.             return;
  32.         } else {
  33.             int32_t tm = (l + r) / 2;
  34.             build(a, v*2, l, tm);
  35.             build(a, v*2+1, tm+1, r);
  36.             t[v].merge(t[v*2],t[v*2+1]);
  37.         }
  38.     }
  39.     NODE query(int32_t v, int l, int r) {
  40.         if (l > tr[v] || r < tl[v])
  41.             return zero;
  42.         if (l <= tl[v] && tr[v] <= r) {
  43.             return t[v];
  44.         }
  45.         pushdown(v);
  46.         NODE a,b,ans;
  47.         a=query(v*2, l, r);
  48.         b=query(v*2+1, l, r);
  49.         ans.merge(a,b);
  50.         return ans;
  51.     }
  52.     void rupd(int32_t v, int l, int r, UPDATE &val)
  53.     {
  54.         if(l > tr[v] || r < tl[v])
  55.             return;
  56.         if(l <= tl[v] && tr[v] <= r)
  57.         {
  58.             apply(v,val);
  59.             return;
  60.         }
  61.         pushdown(v);
  62.         rupd(v*2,l,r,val);
  63.         rupd(v*2+1,l,r,val);
  64.         t[v].merge(t[v*2],t[v*2+1]);
  65.     }
  66.     template<typename T>
  67.     int descent_right(int l, T x, int32_t v, NODE &prev) {
  68.         if (l > tr[v]) // node is completely out of range
  69.             return len;
  70.         if(l <= tl[v]){ // node is completely in range
  71.             NODE cur;
  72.             cur.merge(prev,t[v]);
  73.             if (!cur.check(x)){ // go further right than this node
  74.                 swap(prev,cur); // merging this node's contribution
  75.                 return len;
  76.             }
  77.             if (tl[v]==tr[v]) {
  78.                 return tr[v];
  79.             }
  80.         }
  81.         pushdown(v);
  82.         int ans=descent_right(l, x, v*2, prev); // trying to find in left child
  83.         if(ans!=len)return ans; // found in left child
  84.         return descent_right(l, x, v*2+1, prev); // finding in right child
  85.     }
  86.     template<typename T>
  87.     int descent_left(int r, T x, int32_t v, NODE &prev) {
  88.         if (r < tl[v]) // node is completely out of range
  89.             return -1;
  90.         if(r >= tr[v]){ // node is completely in range
  91.             NODE cur;
  92.             cur.merge(t[v],prev);
  93.             if (!cur.check(x)){ // go further left than this node
  94.                 swap(cur,prev); // merging this node's contribution
  95.                 return -1;
  96.             }
  97.             if (tl[v]==tr[v]) {
  98.                 return tl[v];
  99.             }
  100.         }
  101.         pushdown(v);
  102.         int ans=descent_left(r, x, v*2+1, prev); // trying to find in right child
  103.         if(ans!=-1)return ans; // found in right child
  104.         return descent_left(r, x, v*2, prev); // finding in left child
  105.     }
  106.    
  107.     int len=maxn;
  108.     void clear(){
  109.         fill(t,t+4*len,zero);
  110.         fill(lazy,lazy+4*len,false);
  111.         fill(upds,upds+4*len,noop);
  112.     }
  113.     template<typename T>
  114.     void build(T a){
  115.         build(a,1,0,len-1);
  116.         built=true;
  117.     }
  118.     template<typename T>
  119.     int descent_right(int l, T x){ // minimum r such that [l...r].check(x) == true, returns segtree.len if not found
  120.         NODE prev=zero;
  121.         return descent_right(l,x,1,prev);
  122.     }
  123.     template<typename T>
  124.     int descent_left(int r, T x){ // maximum l such that [l...r].check(x) == true, returns -1 if not found
  125.         NODE prev=zero;
  126.         return descent_left(r,x,1,prev);
  127.     }
  128.     NODE query(int l,int r){
  129.         if(!built)build(t);
  130.         return query(1,l,r);
  131.     }
  132.     void rupd(int l,int r,UPDATE val){
  133.         if(!built)build(t);
  134.         rupd(1,l,r,val);
  135.     }
  136. };
  137.  
  138. struct node{
  139.     int v = 0;
  140.     node(){}
  141.     node(int val){
  142.         v = val;
  143.     }
  144.     void merge(node &l,node &r)
  145.     {
  146.         v = max(l.v,r,v);
  147.     }
  148.     bool check(int x){
  149.         return false;
  150.     }
  151. };
  152. struct update{
  153.     int v = 0;
  154.     update(){}
  155.     update(int val){
  156.         v = val;
  157.     }
  158.     void combine(update &other,int32_t tl,int32_t tr){
  159.         v += other.v;
  160.     }
  161.     void apply(node &x,int32_t tl,int32_t tr){
  162.         x.v += v;
  163.     }
  164. };
  165. segtree<node,update> t;
Add Comment
Please, Sign In to add comment