模板
基数排序
1 const int N = 1e5 + 10; 2 int n, a[N]; 3 4 void radix_sort(unsigned int *a, int l, int r) 5 { 6 const unsigned int D = 1 << 16, k = D - 1; 7 static unsigned int b[N]; static int cnt[D]; 8 unsigned int *x = a, *y = b; 9 for (int i = 0; i < 32; i += 16) 10 { 11 for (int j = 0; j < D; ++j) cnt[j] = 0; 12 for (int j = l; j < r; ++j) ++cnt[x[j] >> i & k]; 13 for (int tot = 0, j = 0; j < D; ++j) tot += cnt[j], cnt[j] = tot - cnt[j]; 14 for (int j = l; j < r; ++j) y[++cnt[x[j] >> i & k]] = x[j]; 15 swap(x, y); 16 } 17 } 18 19 int main() 20 { 21 read(n); for (int i = 1; i <= n; ++i) read(a[i]); 22 radix_sort((unsigned int*)a, 1, n + 1); // 左闭右开 a[l,r) 23 for (int i = 1; i <= n; ++i) print(a[i]), pc(' '); 24 fwrite(pbuf, 1, pp - pbuf, stdout); return 0; 25 }
哈希表(拉链法)
注:答案不存在时返回 $-1$。
1 struct node 2 { 3 int _x1, _y1, _x2, _y2; 4 node() {} 5 node(int a, int b, int c, int d) : _x1(a), _y1(b), _x2(c), _y2(d) {} 6 inline bool operator == (const node &x) const 7 { 8 return _x1 == x._x1 && _y1 == x._y1 && _x2 == x._x2 && _y2 == x._y2; 9 } 10 }; 11 12 struct hash_table 13 { 14 static const int P = 1e7 + 19; 15 const ll b1 = 131, b2 = b1 * b1, b3 = b2 * b1; 16 int tot, h[P]; 17 struct data 18 { 19 node x; ll val; int nxt; 20 data() {} 21 data(node _x, ll _val, int _nxt) : x(_x), val(_val), nxt(_nxt) {} 22 } e[P << 1]; 23 24 inline void clear() { tot = 0, memset(h, 0, sizeof(h)); } 25 inline int hash(node x) { return (x._x1 * b3 + x._y1 * b2 + x._x2 * b1 + x._y2) % P; } 26 27 inline ll& operator [] (node x) 28 { 29 int pos = hash(x); 30 for (int i = h[pos]; i; i = e[i].nxt) 31 if (e[i].x == x) return e[i].val; 32 e[++tot] = data(x, -1, h[pos]), h[pos] = tot; 33 return e[tot].val; 34 } 35 } Map;
树状数组上倍增 CF1354D Multiset
1 const int N = (1 << 20) + 20; 2 int n, q, t[N]; 3 4 inline int lowbit(int x) { return x & -x; } 5 inline void add(int x, int v) 6 { 7 for (; x < N; x += lowbit(x)) t[x] += v; 8 } 9 inline int kth(int k) 10 { 11 int x = 0; 12 for (int i = 19; i >= 0; --i) 13 if (t[x + (1 << i)] < k) x += 1 << i, k -= t[x]; 14 return ++x; 15 } 16 17 int main() 18 { 19 read(n, q); int x; 20 for (int i = 1; i <= n; ++i) read(x), add(x, 1); 21 while (q--) read(x), x > 0 ? add(x, 1) : add(kth(-x), -1); 22 int ans = kth(1); print(ans > n ? 0 : ans); 23 flush_pbuf(); return 0; 24 }
动态开点线段树 CF915E Physical Education Lessons
1 const int N = 3e5 + 10; 2 int n, q, cnt, rt; 3 struct node 4 { 5 int ls, rs, sum, tag; 6 node(int ls = 0, int rs = 0, int sum = 0, int tag = 0) : 7 ls(ls), rs(rs), sum(sum), tag(tag) {} 8 } t[N * 50]; 9 10 inline void pushup(int x) { t[x].sum = t[t[x].ls].sum + t[t[x].rs].sum; } 11 12 inline void pushdown(int x, int len) 13 { 14 if (!t[x].tag) return; 15 if (!t[x].ls) t[x].ls = ++cnt; 16 if (!t[x].rs) t[x].rs = ++cnt; 17 if (t[x].tag == 1) 18 { 19 t[t[x].ls].sum = 0, t[t[x].ls].tag = 1; 20 t[t[x].rs].sum = 0, t[t[x].rs].tag = 1; 21 } 22 else 23 { 24 t[t[x].ls].sum = len - (len >> 1), t[t[x].ls].tag = 2; 25 t[t[x].rs].sum = len >> 1, t[t[x].rs].tag = 2; 26 } 27 t[x].tag = 0; 28 } 29 30 void modify(int &x, int l, int r, int ml, int mr, int k) 31 { 32 if (!x) x = ++cnt; 33 if (ml <= l && r <= mr) 34 return t[x].sum = k == 1 ? 0 : r - l + 1, t[x].tag = k, void(); 35 int mid = l + r >> 1; 36 pushdown(x, r - l + 1); 37 if (ml <= mid) modify(t[x].ls, l, mid, ml, mr, k); 38 if (mid < mr) modify(t[x].rs, mid + 1, r, ml, mr, k); 39 pushup(x); 40 } 41 42 int main() 43 { 44 read(n, q), modify(rt, 1, n, 1, n, 2); int l, r, k; 45 while (q--) read(l, r, k), modify(rt, 1, n, l, r, k), print(t[rt].sum, '\n'); 46 flush_pbuf(); return 0; 47 }
Splay 写法 1
这种写法是查询排名(该数不存在时)和前驱后继(该数不为根节点时)都必须先插入再计算后删除,好写但是常数巨大到爆炸。
1 struct Splay 2 { 3 static const int N = 1.1e6 + 10; 4 int rt, tot, fa[N], ch[N][2], sz[N], cnt[N], val[N]; 5 6 inline void clear(int x) { fa[x] = ch[x][0] = ch[x][1] = sz[x] = cnt[x] = val[x] = 0; } 7 inline bool judge(int x) { return x == ch[fa[x]][1]; } 8 inline void pushup(int x) { sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + cnt[x]; } 9 inline void rotate(int x) 10 { 11 int y = fa[x], z = fa[y], w = judge(x); 12 ch[y][w] = ch[x][!w]; if (ch[x][!w]) fa[ch[x][!w]] = y; 13 if (z) ch[z][judge(y)] = x; ch[x][!w] = y, fa[y] = x, fa[x] = z; 14 pushup(y), pushup(x); 15 } 16 inline void splay(int x) 17 { 18 for (int f = fa[x]; f; rotate(x), f = fa[x]) 19 if (fa[f]) rotate(judge(f) == judge(x) ? f : x); 20 rt = x; 21 } 22 23 inline int rk(int x) 24 { 25 for (int cur = rt, res = 0; ; ) 26 if (x < val[cur]) cur = ch[cur][0]; 27 else if (x == val[cur]) { res += sz[ch[cur][0]]; splay(cur); return res + 1; } 28 else res += sz[ch[cur][0]] + cnt[cur], cur = ch[cur][1]; 29 } 30 inline int xth(int x) 31 { 32 for (int cur = rt; ; ) 33 { 34 if (x <= sz[ch[cur][0]]) cur = ch[cur][0]; 35 else if (x <= sz[ch[cur][0]] + cnt[cur]) { splay(cur); return cur; } 36 else x -= sz[ch[cur][0]] + cnt[cur], cur = ch[cur][1]; 37 } 38 } 39 inline int pre() 40 { 41 int cur = ch[rt][0]; 42 if (!cur) return cur; 43 while (ch[cur][1]) cur = ch[cur][1]; 44 splay(cur); return cur; 45 } 46 inline int nxt() 47 { 48 int cur = ch[rt][1]; 49 if (!cur) return cur; 50 while (ch[cur][0]) cur = ch[cur][0]; 51 splay(cur); return cur; 52 } 53 inline void ins(int x) 54 { 55 if (!rt) val[++tot] = x, ++cnt[tot], rt = tot, pushup(rt); 56 else for (int cur = rt, f = 0; ; f = cur, cur = ch[cur][val[cur] < x]) 57 if (val[cur] == x) { ++cnt[cur], pushup(cur), pushup(f), splay(cur); break; } 58 else if (!cur) 59 { 60 val[++tot] = x, ++cnt[tot], fa[tot] = f, ch[f][val[f] < x] = tot; 61 pushup(tot), pushup(f), splay(tot); break; 62 } 63 } 64 inline void del(int x) 65 { 66 rk(x); int tmp = rt; 67 if (cnt[rt] > 1) --cnt[rt], pushup(rt); 68 else if (!ch[rt][0] && !ch[rt][1]) clear(rt), rt = 0; 69 else if (!ch[rt][0]) rt = ch[rt][1], fa[rt] = 0, clear(tmp); 70 else if (!ch[rt][1]) rt = ch[rt][0], fa[rt] = 0, clear(tmp); 71 else rt = pre(), fa[ch[tmp][1]] = rt, ch[rt][1] = ch[tmp][1], pushup(rt), clear(tmp); 72 } 73 } t;
Splay 写法 2
这种写法需要注意一开始要插入极大极小值。
1 struct Splay 2 { 3 static const int N = 1.1e6 + 10; 4 int rt, tot, fa[N], ch[N][2], sz[N], cnt[N], val[N]; 5 6 inline void clear(int x) { fa[x] = ch[x][0] = ch[x][1] = sz[x] = cnt[x] = val[x] = 0; } 7 inline bool judge(int x) { return x == ch[fa[x]][1]; } 8 inline void pushup(int x) { sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + cnt[x]; } 9 inline void rotate(int x) 10 { 11 int y = fa[x], z = fa[y], w = judge(x); 12 ch[y][w] = ch[x][!w]; if (ch[x][!w]) fa[ch[x][!w]] = y; 13 if (z) ch[z][judge(y)] = x; ch[x][!w] = y, fa[y] = x, fa[x] = z; 14 pushup(y), pushup(x); 15 } 16 inline void splay(int x) 17 { 18 for (int f = fa[x]; f; rotate(x), f = fa[x]) 19 if (fa[f]) rotate(judge(f) == judge(x) ? f : x); 20 rt = x; 21 } 22 23 inline int rk(int x) 24 { 25 int cur = rt, las = rt, res = 0; 26 while (cur) 27 if (x < val[cur]) las = cur, cur = ch[cur][0]; 28 else if (x == val[cur]) { res += sz[ch[cur][0]]; break; } 29 else res += sz[ch[cur][0]] + cnt[cur], las = cur, cur = ch[cur][1]; 30 cur ? splay(cur) : splay(las); return res + 1; 31 } 32 inline int xth(int x) 33 { 34 int cur = rt, las = rt; 35 while (true) 36 if (x <= sz[ch[cur][0]]) las = cur, cur = ch[cur][0]; 37 else if (x <= sz[ch[cur][0]] + cnt[cur]) break; 38 else x -= sz[ch[cur][0]] + cnt[cur], las = cur, cur = ch[cur][1]; 39 cur ? splay(cur) : splay(las); return cur; 40 } 41 inline int pre(int x) 42 { 43 int cur = rt, las = rt, res = 0; 44 while (cur) 45 if (x <= val[cur]) las = cur, cur = ch[cur][0]; 46 else res = las = cur, cur = ch[cur][1]; 47 splay(las); return res; 48 } 49 inline int nxt(int x) 50 { 51 int cur = rt, las = rt, res = 0; 52 while (cur) 53 if (x >= val[cur]) las = cur, cur = ch[cur][1]; 54 else res = las = cur, cur = ch[cur][0]; 55 splay(las); return res; 56 } 57 inline void ins(int x) 58 { 59 if (!rt) val[++tot] = x, ++cnt[tot], rt = tot, pushup(rt); 60 else for (int cur = rt, f = 0; ; f = cur, cur = ch[cur][x > val[cur]]) 61 if (val[cur] == x) { ++cnt[cur], pushup(cur), pushup(f), splay(cur); break; } 62 else if (!cur) 63 { 64 val[++tot] = x, ++cnt[tot], fa[tot] = f, ch[f][x > val[f]] = tot; 65 pushup(tot), pushup(f), splay(tot); break; 66 } 67 } 68 inline void del(int x) 69 { 70 rk(x); int tmp = rt; 71 if (cnt[rt] > 1) --cnt[rt], pushup(rt); 72 else if (!ch[rt][0] && !ch[rt][1]) clear(rt), rt = 0; 73 else if (!ch[rt][0]) rt = ch[rt][1], fa[rt] = 0, clear(tmp); 74 else if (!ch[rt][1]) rt = ch[rt][0], fa[rt] = 0, clear(tmp); 75 else rt = pre(x), splay(rt), fa[ch[tmp][1]] = rt, ch[rt][1] = ch[tmp][1], pushup(rt), clear(tmp); 76 } 77 } t;
树剖(重链剖分)
P3384 【模板】轻重链剖分/树链剖分
1 const int N = 1e5 + 10; 2 int n, m, rt, tim, a[N]; 3 int sz[N], dep[N], fa[N], son[N], top[N], dfn[N], id[N]; 4 ll P, s[N << 2], tag[N << 2]; 5 vector<int> to[N]; 6 7 void dfs1(int u) 8 { 9 sz[u] = 1, dep[u] = dep[fa[u]] + 1; 10 for (int v : to[u]) if (v != fa[u]) 11 { 12 fa[v] = u, dfs1(v), sz[u] += sz[v]; 13 if (sz[v] > sz[son[u]]) son[u] = v; 14 } 15 } 16 17 void dfs2(int u, int x) 18 { 19 top[u] = x, dfn[u] = ++tim, id[tim] = u; 20 if (son[u]) dfs2(son[u], x); 21 for (int v : to[u]) 22 if (v != fa[u] && v != son[u]) dfs2(v, v); 23 } 24 25 inline void addmod(ll &x) { if (x >= P) x -= P; } 26 inline int ls(int x) { return x << 1; } 27 inline int rs(int x) { return x << 1 | 1; } 28 inline void pushup(int x) { s[x] = s[ls(x)] + s[rs(x)], addmod(s[x]); } 29 30 inline void pushdown(int x, int len) 31 { 32 s[ls(x)] += tag[x] * (len - (len >> 1)) % P, addmod(s[ls(x)]); 33 s[rs(x)] += tag[x] * (len >> 1) % P, addmod(s[rs(x)]); 34 tag[ls(x)] += tag[x], addmod(tag[ls(x)]); 35 tag[rs(x)] += tag[x], addmod(tag[rs(x)]); 36 tag[x] = 0; 37 } 38 39 void build(int x, int l, int r) 40 { 41 if (l == r) { s[x] = a[id[l]]; return; } 42 int mid = l + r >> 1; 43 if (l <= mid) build(ls(x), l, mid); 44 if (mid < r) build(rs(x), mid + 1, r); 45 pushup(x); 46 } 47 48 void modify(int x, int l, int r, int ml, int mr, ll v) 49 { 50 if (ml <= l && r <= mr) 51 { 52 s[x] += v * (r - l + 1) % P, addmod(s[x]); 53 tag[x] += v, addmod(tag[x]); 54 return; 55 } 56 pushdown(x, r - l + 1); 57 int mid = l + r >> 1; 58 if (ml <= mid) modify(ls(x), l, mid, ml, mr, v); 59 if (mid < mr) modify(rs(x), mid + 1, r, ml, mr, v); 60 pushup(x); 61 } 62 63 ll query(int x, int l, int r, int ql, int qr) 64 { 65 if (ql <= l && r <= qr) return s[x]; 66 pushdown(x, r - l + 1); 67 int mid = l + r >> 1; ll ans = 0; 68 if (ql <= mid) ans += query(ls(x), l, mid, ql, qr), addmod(ans); 69 if (mid < qr) ans += query(rs(x), mid + 1, r, ql, qr), addmod(ans); 70 return ans; 71 } 72 73 inline void modifytree(int x, ll v) { modify(1, 1, n, dfn[x], dfn[x] + sz[x] - 1, v); } 74 inline ll querytree(int x) { return query(1, 1, n, dfn[x], dfn[x] + sz[x] - 1); } 75 76 inline void modifypath(int u, int v, ll w) 77 { 78 while (top[u] != top[v]) 79 { 80 if (dep[top[u]] < dep[top[v]]) swap(u, v); 81 modify(1, 1, n, dfn[top[u]], dfn[u], w); 82 u = fa[top[u]]; 83 } 84 if (dep[u] > dep[v]) swap(u, v); 85 modify(1, 1, n, dfn[u], dfn[v], w); 86 } 87 88 inline ll querypath(int u, int v) 89 { 90 ll ans = 0; 91 while (top[u] != top[v]) 92 { 93 if (dep[top[u]] < dep[top[v]]) swap(u, v); 94 ans += query(1, 1, n, dfn[top[u]], dfn[u]), addmod(ans); 95 u = fa[top[u]]; 96 } 97 if (dep[u] > dep[v]) swap(u, v); 98 ans += query(1, 1, n, dfn[u], dfn[v]), addmod(ans); 99 return ans; 100 } 101 102 int main() 103 { 104 read(n, m, rt, P); 105 for (int i = 1; i <= n; ++i) read(a[i]); 106 for (int u, v, i = 1; i < n; ++i) 107 read(u, v), to[u].emplace_back(v), to[v].emplace_back(u); 108 dfs1(rt), dfs2(rt, rt), build(1, 1, n); 109 while (m--) 110 { 111 int op, x, y, z; read(op); 112 switch (op) 113 { 114 case 1: 115 read(x, y, z), modifypath(x, y, z); break; 116 case 2: 117 read(x, y), print(querypath(x, y), '\n'); break; 118 case 3: 119 read(x, z), modifytree(x, z); break; 120 case 4: 121 read(x), print(querytree(x), '\n'); break; 122 } 123 } 124 flush_pbuf(); return 0; 125 }
fhq-treap
P6136 【模板】普通平衡树(数据加强版)
1 const int N = 1.1e6 + 10; 2 int n, m, rt, cnt; 3 struct node 4 { 5 int sz, ls, rs, val, rnd; 6 node() {} 7 node(int _sz, int _ls, int _rs, int _val, int _rnd) : 8 sz(_sz), ls(_ls), rs(_rs), val(_val), rnd(_rnd) {} 9 } t[N]; 10 mt19937 Rand(time(0)); 11 12 inline int newnode(int v) { t[++cnt] = node(1, 0, 0, v, Rand()); return cnt; } 13 inline void pushup(int x) { t[x].sz = t[t[x].ls].sz + t[t[x].rs].sz + 1; } 14 15 void split(int x, int k, int &l, int &r) 16 { 17 if (!x) { l = r = 0; return; } 18 if (t[x].val <= k) l = x, split(t[x].rs, k, t[x].rs, r); 19 else r = x, split(t[x].ls, k, l, t[x].ls); 20 pushup(x); 21 } 22 int merge(int x, int y) 23 { 24 if (!x || !y) return x | y; 25 if (t[x].rnd < t[y].rnd) { t[x].rs = merge(t[x].rs, y), pushup(x); return x; } 26 else { t[y].ls = merge(x, t[y].ls), pushup(y); return y; } 27 } 28 inline int kth(int x, int k) 29 { 30 while (true) 31 if (k <= t[t[x].ls].sz) x = t[x].ls; 32 else if (k == t[t[x].ls].sz + 1) return x; 33 else k -= t[t[x].ls].sz + 1, x = t[x].rs; 34 } 35 36 inline void ins(int v) 37 { 38 int x, y; split(rt, v, x, y); 39 rt = merge(merge(x, newnode(v)), y); 40 } 41 inline void del(int v) 42 { 43 int x, y, z; split(rt, v, x, z), split(x, v - 1, x, y); 44 y = merge(t[y].ls, t[y].rs), rt = merge(merge(x, y), z); 45 } 46 inline int rk(int v) 47 { 48 int x, y, k; split(rt, v - 1, x, y); 49 k = t[x].sz + 1, rt = merge(x, y); 50 return k; 51 } 52 inline int pre(int v) 53 { 54 int x, y, w; split(rt, v - 1, x, y); 55 w = t[kth(x, t[x].sz)].val, rt = merge(x, y); 56 return w; 57 } 58 inline int nxt(int v) 59 { 60 int x, y, w; split(rt, v, x, y); 61 w = t[kth(y, 1)].val, rt = merge(x, y); 62 return w; 63 } 64 65 int main() 66 { 67 read(n, m); int lastans = 0, ans = 0; 68 for (int x, i = 1; i <= n; ++i) read(x), ins(x); 69 while (m--) 70 { 71 int op, x; read(op, x), x ^= lastans; 72 switch (op) 73 { 74 case 1: ins(x); break; 75 case 2: del(x); break; 76 case 3: lastans = rk(x); break; 77 case 4: lastans = t[kth(rt, x)].val; break; 78 case 5: lastans = pre(x); break; 79 case 6: lastans = nxt(x); break; 80 } 81 if (op >= 3) ans ^= lastans; 82 } 83 print(ans); 84 flush_pbuf(); return 0; 85 }
P3391 【模板】文艺平衡树
1 const int N = 1e5 + 10; 2 int n, m, rt, cnt; 3 struct node 4 { 5 int sz, ls, rs, val, rnd, tag; 6 node() {} 7 node(int _sz, int _ls, int _rs, int _val, int _rnd, int _tag) : 8 sz(_sz), ls(_ls), rs(_rs), val(_val), rnd(_rnd), tag(_tag) {} 9 } t[N]; 10 mt19937 Rand(time(0)); 11 12 inline int newnode(int v) { t[++cnt] = node(1, 0, 0, v, Rand(), 0); return cnt; } 13 inline void pushup(int x) { t[x].sz = t[t[x].ls].sz + t[t[x].rs].sz + 1; } 14 inline void pushdown(int x) 15 { 16 if (!t[x].tag) return; 17 if (t[x].ls) t[t[x].ls].tag ^= 1; 18 if (t[x].rs) t[t[x].rs].tag ^= 1; 19 swap(t[x].ls, t[x].rs), t[x].tag = 0; 20 } 21 22 void split(int x, int k, int &l, int &r) 23 { 24 if (!x) { l = r = 0; return; } 25 pushdown(x); 26 if (t[t[x].ls].sz < k) l = x, split(t[x].rs, k - t[t[x].ls].sz - 1, t[x].rs, r); 27 else r = x, split(t[x].ls, k, l, t[x].ls); 28 pushup(x); 29 } 30 int merge(int x, int y) 31 { 32 if (!x || !y) return x | y; 33 pushdown(x), pushdown(y); 34 if (t[x].rnd < t[y].rnd) { t[x].rs = merge(t[x].rs, y), pushup(x); return x; } 35 else { t[y].ls = merge(x, t[y].ls), pushup(y); return y; } 36 } 37 38 inline void ins(int v, int k) 39 { 40 int x, y; split(rt, k - 1, x, y); 41 rt = merge(merge(x, newnode(v)), y); 42 } 43 inline void rev(int l, int r) 44 { 45 int x, y, z; split(rt, l - 1, x, y), split(y, r - l + 1, y, z); 46 t[y].tag ^= 1, rt = merge(merge(x, y), z); 47 } 48 49 int main() 50 { 51 read(n, m); int l, r, x, y; 52 for (int i = 1; i <= n; ++i) ins(i, i); 53 while (m--) read(l, r), rev(l, r); x = rt; 54 for (int i = 1; i <= n; ++i) 55 split(x, 1, x, y), print(t[x].val, ' '), swap(x, y); 56 flush_pbuf(); return 0; 57 }
P2042 [NOI2005] 维护数列
1 const int N = 5e5 + 10, inf = 1e9; 2 int n, m, rt, cnt, top, a[N], b[N]; 3 mt19937 Rand((unsigned)time(0)); 4 5 struct Res 6 { 7 int sum, lmax, rmax, ans; 8 Res(int sum = 0, int lmax = -inf, int rmax = -inf, int ans = -inf) : 9 sum(sum), lmax(lmax), rmax(rmax), ans(ans) {} 10 }; 11 inline Res operator + (const Res &x, const Res &y) 12 { 13 Res z; z.sum = x.sum + y.sum; 14 z.lmax = Max(x.lmax, x.sum + y.lmax, -inf); 15 z.rmax = Max(y.rmax, y.sum + x.rmax, -inf); 16 z.ans = Max(x.ans, y.ans, x.rmax + y.lmax, -inf); 17 return z; 18 } 19 20 struct node 21 { 22 int sz, ls, rs, val, rnd, tag, rev; Res res; 23 node(int sz = 0, int ls = 0, int rs = 0, int val = 0, 24 int rnd = 0, int tag = inf, int rev = 0, Res res = Res(0, -inf, -inf, -inf)) : 25 sz(sz), ls(ls), rs(rs), val(val), rnd(rnd), tag(tag), rev(rev), res(res) {} 26 } t[N]; 27 28 inline int newnode(int v) 29 { 30 int x = top ? b[top--] : ++cnt; 31 t[x] = node(1, 0, 0, v, Rand(), inf, 0, Res(v, v, v, v)); 32 return x; 33 } 34 inline void pushup(int x) 35 { 36 t[x].sz = t[t[x].ls].sz + t[t[x].rs].sz + 1; 37 t[x].res = t[t[x].ls].res + Res(t[x].val, t[x].val, t[x].val, t[x].val) + t[t[x].rs].res; 38 } 39 inline void Cover(int x, int v) 40 { 41 t[x].tag = t[x].val = v, t[x].rev = 0, t[x].res.sum = t[x].sz * v; 42 if (v > 0) t[x].res.lmax = t[x].res.rmax = t[x].res.ans = t[x].res.sum; 43 else t[x].res.lmax = t[x].res.rmax = t[x].res.ans = v; 44 } 45 inline void Reverse(int x) 46 { 47 t[x].rev ^= 1, swap(t[x].res.lmax, t[x].res.rmax), swap(t[x].ls, t[x].rs); 48 } 49 inline void pushdown(int x) 50 { 51 if (t[x].tag != inf) 52 { 53 if (t[x].ls) Cover(t[x].ls, t[x].tag); 54 if (t[x].rs) Cover(t[x].rs, t[x].tag); 55 t[x].tag = inf; 56 } 57 if (t[x].rev) 58 { 59 if (t[x].ls) Reverse(t[x].ls); 60 if (t[x].rs) Reverse(t[x].rs); 61 t[x].rev = 0; 62 } 63 } 64 65 void split(int x, int k, int &l, int &r) 66 { 67 if (!x) { l = r = 0; return; } 68 pushdown(x); 69 if (t[t[x].ls].sz < k) l = x, split(t[x].rs, k - t[t[x].ls].sz - 1, t[x].rs, r); 70 else r = x, split(t[x].ls, k, l, t[x].ls); 71 pushup(x); 72 } 73 int merge(int x, int y) 74 { 75 if (!x || !y) return x | y; 76 if (t[x].rnd < t[y].rnd) { pushdown(x), t[x].rs = merge(t[x].rs, y), pushup(x); return x; } 77 else { pushdown(y), t[y].ls = merge(x, t[y].ls), pushup(y); return y; } 78 } 79 80 void midorder(int x) 81 { 82 if (t[x].ls) midorder(t[x].ls); 83 cerr << t[x].val << ' '; 84 if (t[x].rs) midorder(t[x].rs); 85 } 86 int build(int l, int r) 87 { 88 if (l > r) return 0; 89 int mid = l + r >> 1, x = newnode(a[mid]); 90 if (l == r) return x; 91 t[x].ls = build(l, mid - 1); 92 t[x].rs = build(mid + 1, r); 93 pushup(x); return x; 94 } 95 void recycle(int x) 96 { 97 b[++top] = x; 98 if (t[x].ls) recycle(t[x].ls); 99 if (t[x].rs) recycle(t[x].rs); 100 } 101 102 inline void ins(int k, int x) 103 { 104 int y, z; split(rt, k, y, z); 105 rt = merge(merge(y, x), z); 106 } 107 inline void del(int k, int tot) 108 { 109 int x, y, z; split(rt, k - 1, x, y), split(y, tot, y, z); 110 rt = merge(x, z), recycle(y); 111 } 112 inline void same(int k, int tot, int v) 113 { 114 int x, y, z; split(rt, k - 1, x, y), split(y, tot, y, z); 115 Cover(y, v), rt = merge(merge(x, y), z); 116 } 117 inline void rev(int k, int tot) 118 { 119 int x, y, z; split(rt, k - 1, x, y), split(y, tot, y, z); 120 Reverse(y), rt = merge(merge(x, y), z); 121 } 122 inline int getsum(int k, int tot) 123 { 124 int x, y, z, tmp; split(rt, k - 1, x, y), split(y, tot, y, z); 125 tmp = t[y].res.sum, rt = merge(merge(x, y), z); return tmp; 126 } 127 inline int maxsum() { return t[rt].res.ans; } 128 129 int main() 130 { 131 read(n, m); 132 for (int i = 1; i <= n; ++i) read(a[i]); 133 rt = build(1, n); 134 while (m--) 135 { 136 137 char s[10]; read(s); int x, y, z; 138 switch (s[0]) 139 { 140 case 'I': 141 read(x, y); 142 for (int i = 1; i <= y; ++i) read(a[i]); 143 ins(x, build(1, y)); break; 144 case 'D': 145 read(x, y), del(x, y); break; 146 case 'M': 147 if (s[2] == 'K') read(x, y, z), same(x, y, z); 148 else print(maxsum(), '\n'); break; 149 case 'R': 150 read(x, y), rev(x, y); break; 151 case 'G': 152 read(x, y), print(getsum(x, y), '\n'); break; 153 } 154 // midorder(rt), cerr << '\n'; 155 } 156 flush_pbuf(); return 0; 157 }
可持久化数据结构
可持久化下标线段树:P3919 【模板】可持久化线段树 1(可持久化数组)
1 const int N = 1e6 + 10; 2 int n, m, top, a[N], rt[N]; 3 struct node 4 { 5 int ls, rs, v; 6 node(int ls = 0, int rs = 0, int v = 0) : 7 ls(ls), rs(rs), v(v) {} 8 } t[N * 24]; 9 10 void build(int &x, int l, int r) 11 { 12 x = ++top; 13 if (l == r) { t[x].v = a[l]; return; } 14 int mid = l + r >> 1; 15 build(t[x].ls, l, mid); 16 build(t[x].rs, mid + 1, r); 17 } 18 19 void modify(int &x, int pre, int l, int r, int p, int v) 20 { 21 x = ++top, t[x] = t[pre]; 22 if (l == r) { t[x].v = v; return; } 23 int mid = l + r >> 1; 24 if (p <= mid) modify(t[x].ls, t[pre].ls, l, mid, p, v); 25 if (mid < p) modify(t[x].rs, t[pre].rs, mid + 1, r, p, v); 26 } 27 28 int query(int &x, int l, int r, int p) 29 { 30 if (l == r) return t[x].v; 31 int mid = l + r >> 1; 32 if (p <= mid) return query(t[x].ls, l, mid, p); 33 else return query(t[x].rs, mid + 1, r, p); 34 } 35 36 int main() 37 { 38 read(n, m); 39 for (int i = 1; i <= n; ++i) read(a[i]); 40 build(rt[0], 1, n); 41 for (int k, op, p, v, i = 1; i <= m; ++i) 42 { 43 read(k, op, p); 44 if (op == 1) read(v), modify(rt[i], rt[k], 1, n, p, v); 45 else print(query(rt[i] = rt[k], 1, n, p), '\n'); 46 } 47 flush_pbuf(); return 0; 48 }
可持久化值域线段树:P3834 【模板】可持久化线段树 2
1 const int N = 2e5 + 10; 2 int n, m, top, rt[N]; 3 struct node 4 { 5 int ls, rs, sz; 6 inline node(int ls = 0, int rs = 0, int sz = 0) : 7 ls(ls), rs(rs), sz(sz) {} 8 } t[N * 90]; 9 10 inline void pushup(int x) { t[x].sz = t[t[x].ls].sz + t[t[x].rs].sz; } 11 12 void insert(int &x, int pre, int l, int r, int v) 13 { 14 x = ++top, t[x] = t[pre]; 15 if (l == r) { ++t[x].sz; return; } 16 int mid = l + r >> 1; 17 if (v <= mid) insert(t[x].ls, t[pre].ls, l, mid, v); 18 if (mid < v) insert(t[x].rs, t[pre].rs, mid + 1, r, v); 19 pushup(x); 20 } 21 22 int query(int x, int y, int l, int r, int k) 23 { 24 if (l == r) return l; 25 int mid = l + r >> 1, cnt = t[t[y].ls].sz - t[t[x].ls].sz; 26 if (k <= cnt) return query(t[x].ls, t[y].ls, l, mid, k); 27 else return query(t[x].rs, t[y].rs, mid + 1, r, k - cnt); 28 } 29 30 int main() 31 { 32 read(n, m); 33 for (int x, i = 1; i <= n; ++i) 34 read(x), insert(rt[i], rt[i - 1], -1e9, 1e9, x); 35 while (m--) 36 { 37 int l, r, k; read(l, r, k); 38 print(query(rt[l - 1], rt[r], -1e9, 1e9, k), '\n'); 39 } 40 flush_pbuf(); return 0; 41 }
可持久化 01 Trie:P4735 最大异或和
1 const int N = 6e5 + 10, LIM = 23; 2 int n, m, cnt, sum, rt[N]; 3 struct node 4 { 5 int ch[2], sz; 6 inline node(int ls = 0, int rs = 0, int sz = 0) : 7 ch{ls, rs}, sz(sz) {} 8 } t[N * 50]; 9 10 inline void pushup(int x) { t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz; } 11 12 void insert(int &x, int pre, int dep, int v) 13 { 14 x = ++cnt, t[x] = t[pre]; 15 if (dep < 0) { ++t[x].sz; return; } 16 int c = v >> dep & 1; 17 insert(t[x].ch[c], t[pre].ch[c], dep - 1, v); 18 pushup(x); 19 } 20 21 int query(int x, int y, int dep, int v) 22 { 23 if (dep < 0) return 0; 24 int c = v >> dep & 1; 25 if (t[t[y].ch[!c]].sz - t[t[x].ch[!c]].sz > 0) 26 return (1 << dep) + query(t[x].ch[!c], t[y].ch[!c], dep - 1, v); 27 else return query(t[x].ch[c], t[y].ch[c], dep - 1, v); 28 } 29 30 int main() 31 { 32 read(n, m), insert(rt[0], rt[0], LIM, sum); 33 for (int x, i = 1; i <= n; ++i) 34 read(x), insert(rt[i], rt[i - 1], LIM, sum ^= x); 35 while (m--) 36 { 37 char op[10]; int l, r, x, res; read(op); 38 if (op[0] == 'A') read(x), ++n, insert(rt[n], rt[n - 1], LIM, sum ^= x); 39 else 40 { 41 read(l, r, x); 42 if (l == 1) print(query(0, rt[r - 1], LIM, sum ^ x), '\n'); 43 else print(query(rt[l - 2], rt[r - 1], LIM, sum ^ x), '\n'); 44 } 45 } 46 flush_pbuf(); return 0; 47 }
To be continued...