| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 
 | template<class info>struct SMT {
 int L, R, pcnt;
 vector<info> t;
 vector<int> ls, rs;
 vector<int> rt;
 
 SMT() {
 init(0, 0);
 t.resize(N << 2);
 ls.resize(N << 2);
 rs.resize(N << 2);
 }
 
 void init(int l, int r) {
 L = l, R = r;
 pcnt = 0;
 rt.assign(N, 0);
 }
 
 void init(int p) {
 t[p] = info();
 ls[p] = rs[p] = 0;
 }
 
 #define mid ((L+R)>>1)
 #define len (R-L)
 #define lson ls[p],L,mid
 #define rson rs[p],mid,R
 
 void push_up(int& p) {
 t[p] = t[ls[p]] + t[rs[p]];
 }
 
 void modify(int x, const info& d, int& p, int L, int R) {
 if (!p) p = ++pcnt, init(p);
 if (R - L < 2) return t[p].apply(d);
 if (x < mid) modify(x, d, lson);
 else modify(x, d, rson);
 return push_up(p);
 }
 void modify(int x, const info& d, int p) {
 modify(x, d, rt[p], L, R);
 }
 
 info query(int l, int r, int& p, int L, int R) {
 if (l <= L && R <= r) return t[p];
 info res = info();
 if (l < mid) res = res + query(l, r, lson);
 if (mid < r) res = res + query(l, r, rson);
 return res;
 }
 info query(int l, int r, int& p) {
 return query(l, r, rt[p], L, R);
 }
 
 void merge(int& q, int& p, int L, int R) {
 if (!q || !p) return q |= p, void();
 if (R - L < 2) return t[q].apply(t[p]);
 merge(ls[q], lson);
 merge(rs[q], rson);
 return push_up(q);
 }
 void merge(int& q, int& p) {
 return merge(rt[q], rt[p], L, R);
 }
 };
 
 |