Advertisement
i_love_rao_khushboo

All-Purpose Generic Segment Tree.cpp

Oct 14th, 2021 (edited)
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.08 KB | None | 0 0
  1. /*
  2. KEYNOTES:
  3. ------------------------------------------------------------------------------------------
  4. merge(X,identity_element) = X
  5. ------------------------------------------------------------------------------------------
  6. // (i.e no transformation at all or if we combine any new update with the identity update
  7. // it should give the newer update)
  8. identity_transformation.combine(X) = X
  9. ------------------------------------------------------------------------------------------
  10. ALWAYS: older_update.combine(newer_update)
  11. ------------------------------------------------------------------------------------------
  12. */
  13.  
  14. // this structure depends on the nature of query
  15. struct node {
  16.     // 1. change(s) required
  17.     // use more variables if you want more information
  18.     // these default values should be identity_element
  19.    
  20.        
  21.     node() {}
  22.     node(int ) {
  23.         // 2. change(s) required
  24.        
  25.     }
  26.    
  27.     // associative merging function, store the thing you wanna query
  28.     void merge(const node &l, const node &r){
  29.         // 3. change(s) required
  30.        
  31.     }
  32. };
  33.  
  34. // this structure depends on the nature of update
  35. struct update {
  36.     // 4. change(s) required
  37.     // use more variables if you want more information
  38.     // these default values should be identity_transformation or identity_update
  39.    
  40.    
  41.     update() {}
  42.     update(int ) {
  43.         // 5. change(s) required
  44.        
  45.     }
  46.    
  47.     // combine the current update with the other update (see keynotes)
  48.     // basically combine older lazy value(s) (if exist) with newer one(s).
  49.     // for this function, you can be sure that the "other" is newer than current
  50.     void combine(update &other, const int32_t &tl, const int32_t &tr) {
  51.         // 6. change(s) required
  52.        
  53.     }
  54.    
  55.     // store the correct information in the node x
  56.     void apply(node &x, const int32_t &tl, const int32_t &tr) {
  57.         // 7. change(s) required
  58.        
  59.     }
  60. };
  61.  
  62. template<typename node, typename update>
  63. struct segtree {
  64.     int len;
  65.     vector<node> t;
  66.     vector<update> u;
  67.     vector<bool> lazy;
  68.     node identity_element;
  69.     update identity_transformation;
  70.    
  71.     segtree(int l) {
  72.         len = l;
  73.         t.clear(); t.resize(4 * len);
  74.         u.clear(); u.resize(4 * len);
  75.         lazy.clear(); lazy.resize(4 * len);
  76.         identity_element = node();
  77.         identity_transformation = update();
  78.     }
  79.    
  80.     void pushdown(const int32_t &v, const int32_t &tl, const int32_t &tr) {
  81.         if(!lazy[v]) return;
  82.         int32_t tm = (tl + tr) >> 1;
  83.         apply(v << 1, tl, tm, u[v]);
  84.         apply((v << 1) | 1, tm + 1, tr, u[v]);
  85.         u[v] = identity_transformation;
  86.         lazy[v] = 0;
  87.     }
  88.    
  89.     void apply(const int32_t &v, const int32_t &tl, const int32_t &tr, update upd) {
  90.         if(tl != tr) {
  91.             lazy[v] = 1;
  92.             u[v].combine(upd, tl, tr);
  93.         }
  94.        
  95.         upd.apply(t[v], tl, tr);
  96.     }
  97.    
  98.     template<typename T>
  99.     void build(const T &arr, const int32_t &v, const int32_t &tl, const int32_t &tr) {
  100.         if(tl == tr) {
  101.             t[v] = arr[tl];
  102.             return;
  103.         }
  104.        
  105.         int32_t tm = (tl + tr) >> 1;
  106.         build(arr, v << 1, tl, tm);
  107.         build(arr, (v << 1) | 1, tm + 1, tr);
  108.         t[v].merge(t[v << 1],t[(v << 1) | 1]);
  109.     }
  110.    
  111.     node query(const int32_t &v, const int32_t &tl, const int32_t &tr, const int32_t &l, const int32_t &r) {
  112.         if(l > tr || r < tl) {
  113.             return identity_element;
  114.         }
  115.        
  116.         if(tl >= l && tr <= r){
  117.             return t[v];
  118.         }
  119.        
  120.         pushdown(v, tl, tr);
  121.         int32_t tm = (tl + tr) >> 1;
  122.         node a = query(v << 1, tl, tm, l, r), b = query((v << 1) | 1, tm + 1, tr, l, r), ans;
  123.         ans.merge(a, b);
  124.         return ans;
  125.     }
  126.    
  127.     void rupd(const int32_t &v, const int32_t &tl, const int32_t &tr, const int32_t &l, const int32_t &r, const update &upd) {
  128.         if(l > tr || r < tl){
  129.             return;
  130.         }
  131.        
  132.         if(tl >= l && tr <= r){
  133.             apply(v,tl,tr,upd);
  134.             return;
  135.         }
  136.        
  137.         pushdown(v, tl, tr);
  138.         int32_t tm = (tl + tr) >> 1;
  139.         rupd(v << 1, tl, tm, l, r, upd);
  140.         rupd((v << 1) | 1, tm + 1, tr, l, r, upd);
  141.         t[v].merge(t[v << 1], t[(v << 1) | 1]);
  142.     }
  143.    
  144.     public:
  145.     template<typename T>
  146.     void build(const T &arr) {
  147.         build(arr, 1, 0, len - 1);
  148.     }
  149.    
  150.     node query(const int32_t &l,const int32_t &r) {
  151.         return query(1, 0, len - 1, l, r);
  152.     }
  153.    
  154.     void rupd(const int32_t &l, const int32_t &r, const update &upd) {
  155.         rupd(1, 0, len - 1, l, r, upd);
  156.     }
  157. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement