Saturday, April 4, 2020

[Template] Segment Tree - My Version

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Algorithm         : Segment Tree Lazy Propagation (my version)
Source            : range add range sum : LightOJ 1164 - Horrible Queries
                    range set range sum : LightOJ 1183 - Computing Fast Average
                    range add range max : Codeforces E - Bombs
Algorithm         : 
Verdict           : Tested

  1. template <typename T>  
  2. struct Node {  
  3.       T sum;  
  4.       T maxi;  
  5.       T mini;  
  6.       bool toset;  
  7.       bool toadd;  
  8.       T lazy;  
  9.       Node(T sum = 0, T maxi = numeric_limits <T>::min(), T mini = numeric_limits <T>::max(),  
  10.            bool toset = 0, bool toadd = 0, T lazy = 0)  
  11.            : sum(sum), maxi(maxi), mini(mini), toset(toset), toadd(toadd), lazy(lazy) {}  
  12. };  
  13.   
  14. ll arr[maxn];  
  15.   
  16. template <typename T>  
  17. struct SegmentTree {  
  18.       #define Node             Node <T>  
  19.       #define lchild           node * 2  
  20.       #define rchild           node * 2 + 1  
  21.       #define mid              (int)(a + b) / 2  
  22.   
  23.       int n;  
  24.       vector <Node> st;  
  25.   
  26.       void init(int N) {  
  27.             n = N;  
  28.             st.clear();  
  29.             st.resize(4 * N + 5);  
  30.       }  
  31.       void marge(int node, int a, int b) {  
  32.             st[node].sum = st[lchild].sum + st[rchild].sum;  
  33.             st[node].maxi = max(st[lchild].maxi, st[rchild].maxi);  
  34.             st[node].mini = min(st[lchild].mini, st[rchild].mini);  
  35.       }  
  36.       void build(int node, int a, int b) {  
  37.             if (a == b) {  
  38.                   int val = arr[a];  
  39.                   st[node].sum = val;  
  40.                   st[node].maxi = val;  
  41.                   st[node].mini = val;  
  42.                   return;  
  43.             }  
  44.             build(lchild, a, mid);  
  45.             build(rchild, mid + 1, b);  
  46.             marge(node, a, b);  
  47.       }  
  48.       void propagate1(int node, int a, int b) {  
  49.             if (a != b) {  
  50.                   st[lchild].toset = st[rchild].toset = 1;  
  51.                   st[lchild].toadd = st[rchild].toadd = 0;  
  52.                   st[lchild].lazy = st[rchild].lazy = st[node].lazy;  
  53.             }  
  54.             st[node].maxi = st[node].mini = st[node].lazy;  
  55.             st[node].sum = 1LL * (b - a + 1) * st[node].lazy;  
  56.             st[node].toset = st[node].toadd = 0;  
  57.             st[node].lazy = 0;  
  58.       }  
  59.       void propagate2(int node, int a, int b) {  
  60.             if (a != b) {  
  61.                   st[lchild].toadd = st[rchild].toadd = 1;  
  62.                   st[lchild].lazy += st[node].lazy;  
  63.                   st[rchild].lazy += st[node].lazy;  
  64.             }  
  65.             st[node].sum += 1LL * (b - a + 1) * st[node].lazy;  
  66.             st[node].maxi += st[node].lazy;  
  67.             st[node].mini += st[node].lazy;  
  68.             st[node].toadd = st[node].toset = 0;  
  69.             st[node].lazy = 0;  
  70.       }  
  71.       void update(int node, int a, int b, int i, int j, T val, bool toset) {  
  72.             if (st[node].toset) {  
  73.                   propagate1(node, a, b);  
  74.             }  
  75.             if (st[node].lazy) {  
  76.                   propagate2(node, a, b);  
  77.             }  
  78.             if (a > j or b < i) {  
  79.                   return;  
  80.             }  
  81.             if (a >= i and b <= j) {  
  82.                   if (toset) {  
  83.                         st[node].toset = 1;  
  84.                         st[node].toadd = 0;  
  85.                         st[node].lazy = val;  
  86.                         propagate1(node, a, b);  
  87.                   }  
  88.                   else {  
  89.                         st[node].toset = 0;  
  90.                         st[node].toadd = 1;  
  91.                         st[node].lazy += val;  
  92.                         propagate2(node, a, b);  
  93.                   }  
  94.                   return;  
  95.             }  
  96.             update(lchild, a, mid, i, j, val, toset);  
  97.             update(rchild, mid + 1, b, i, j, val, toset);  
  98.             marge(node, a, b);  
  99.       }  
  100.       Node query(int node, int a, int b, int i, int j) {  
  101.             if (st[node].toset) {  
  102.                   propagate1(node, a, b);  
  103.             }  
  104.             if (st[node].toadd) {  
  105.                   propagate2(node, a, b);  
  106.             }  
  107.             if (a > j or b < i) {  
  108.                   return Node();  
  109.             }  
  110.             if (a >= i and b <= j) {  
  111.                   return st[node];  
  112.             }  
  113.             Node p = query(lchild, a, mid, i, j);  
  114.             Node q = query(rchild, mid + 1, b, i, j);  
  115.             Node res;  
  116.             res.sum = p.sum + q.sum;  
  117.             res.maxi = max(p.maxi, q.maxi);  
  118.             res.mini = min(p.mini, q.mini);  
  119.             marge(node, a, b);  
  120.             return res;  
  121.       }  
  122.       void build() {  
  123.             build(1, 1, n);  
  124.       }  
  125.       void uset(int l, int r, T val) {  
  126.             update(1, 1, n, l, r, val, 1);  
  127.       }  
  128.       void uadd(int l, int r, T val) {  
  129.             update(1, 1, n, l, r, val, 0);  
  130.       }  
  131.       Node query(int l, int r) {  
  132.             return query(1, 1, n, l, r);  
  133.       }  
  134.       T get_sum(int l, int r) {  
  135.             return query(l, r).sum;  
  136.       }  
  137.       T get_maxi(int l, int r) {  
  138.             return query(l, r).maxi;  
  139.       }  
  140.       T get_mini(int l, int r) {  
  141.             return query(l, r).mini;  
  142.       }  
  143.         
  144.       #undef lchild  
  145.       #undef rchild  
  146.       #undef mid  
  147. };  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.