Advertisement
Guest User

Untitled

a guest
Mar 18th, 2021
652
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.86 KB | None | 0 0
  1. template<typename T> struct seg {
  2.     struct node {
  3.         node* ch[2];
  4.         char d;
  5.         T v;
  6.  
  7.         T mi;
  8.  
  9.         node(int d_, T v_, T val) : d(d_), v(v_) {
  10.             ch[0] = ch[1] = NULL;
  11.             mi = val;
  12.         }
  13.         node(node* x) : d(x->d), v(x->v), mi(x->mi) {
  14.             ch[0] = x->ch[0], ch[1] = x->ch[1];
  15.         }
  16.         void update() {
  17.             mi = numeric_limits<T>::max();
  18.             for (int i = 0; i < 2; i++) if (ch[i])
  19.                 mi = min(mi, ch[i]->mi);
  20.         }
  21.     };
  22.  
  23.     node* root;
  24.     char n;
  25.  
  26.     seg() : root(NULL), n(0) {}
  27.     ~seg() {
  28.         std::vector<node*> q = {root};
  29.         while (q.size()) {
  30.             node* x = q.back(); q.pop_back();
  31.             if (!x) continue;
  32.             q.push_back(x->ch[0]), q.push_back(x->ch[1]);
  33.             delete x;
  34.         }
  35.     }
  36.  
  37.     char msb(T v, char l, char r) { // msb in range (l, r]
  38.         for (char i = r; i > l; i--) if (v>>i&1) return i;
  39.         return -1;
  40.     }
  41.     void cut(node* at, T v, char i) {
  42.         char d = msb(v ^ at->v, at->d, i);
  43.         if (d == -1) return; // no need to split
  44.         node* nxt = new node(at);
  45.         at->ch[v>>d&1] = NULL;
  46.         at->ch[!(v>>d&1)] = nxt;
  47.         at->d = d;
  48.     }
  49.  
  50.     node* update(node* at, T idx, T val, char i) {
  51.         if (!at) return new node(-1, idx, val);
  52.         cut(at, idx, i);
  53.         if (at->d == -1) { // leaf
  54.             at->mi = val;
  55.             return at;
  56.         }
  57.         bool dir = idx>>at->d&1;
  58.         at->ch[dir] = update(at->ch[dir], idx, val, at->d-1);
  59.         at->update();
  60.         return at;
  61.     }
  62.     void update(T idx, T val) {
  63.         while (idx>>n) n++;
  64.         root = update(root, idx, val, n-1);
  65.     }
  66.  
  67.     T query(node* at, T a, T b, T l, T r, char i) {
  68.         if (!at or b < l or r < a) return numeric_limits<T>::max();
  69.         if (a <= l and r <= b) return at->mi;
  70.         T m = l + (r-l)/2;
  71.         if (at->d < i) {
  72.             if ((at->v>>i&1) == 0) return query(at, a, b, l, m, i-1);
  73.             else return query(at, a, b, m+1, r, i-1);
  74.         }
  75.         return min(query(at->ch[0], a, b, l, m, i-1), query(at->ch[1], a, b, m+1, r, i-1));
  76.     }
  77.     T query(T l, T r) { return query(root, l, r, 0, (1<<n)-1, n-1); }
  78. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement