模板

基数排序

 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 }
View Code

哈希表(拉链法)

注:答案不存在时返回 $-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;
View Code

树状数组上倍增 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 }
View Code

动态开点线段树 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 }
View Code

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;
View Code

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;
View Code

树剖(重链剖分)

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

可持久化数据结构

可持久化下标线段树: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 }
View Code

可持久化值域线段树: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 }
View Code

可持久化 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 }
View Code

To be continued...

posted @ 2022-03-14 07:48  jhqqwq  阅读(29)  评论(0编辑  收藏  举报