感觉这个玩意就是拆来拆去,所以没啥可学习的
粘一下两个题的代码吧
LGOJ 普通平衡树
#include <bits/stdc++.h> using namespace std; #define int long long namespace yspm { inline int read() { int res = 0, f = 1; char k; while (!isdigit(k = getchar())) if (k == '-') f = -1; while (isdigit(k)) res = res * 10 + k - '0', k = getchar(); return res * f; } const int N = 1e6 + 10, inf = 1e15 + 10; int base = 12344, tot, rt; int val[N], ls[N], rs[N], sz[N], rk[N]; inline int random() { return (base *= 102394) %= 239402, base; } inline int add(int valn) { sz[++tot] = 1; ls[tot] = rs[tot] = 0; val[tot] = valn; rk[tot] = random(); return tot; } inline void update(int rt) { sz[rt] = sz[ls[rt]] + sz[rs[rt]] + 1; return; } inline void split(int rt, int &a, int &b, int valn) { if (!rt) return a = b = 0, void(); if (val[rt] <= valn) a = rt, split(rs[rt], rs[a], b, valn); else b = rt, split(ls[rt], a, ls[b], valn); return update(rt), void(); } inline void merge(int &rt, int a, int b) { if (!b || !a) return rt = a + b, void(); if (rk[a] < rk[b]) rt = a, merge(rs[rt], rs[a], b); else rt = b, merge(ls[rt], a, ls[b]); return update(rt), void(); } inline void insert(int &rt, int val) { int x = 0, y = 0, now = add(val); split(rt, x, y, val); merge(x, x, now); merge(rt, x, y); return; } inline void del(int &rt, int val) { int x = 0, y = 0, z = 0; split(rt, x, y, val); split(x, x, z, val - 1); merge(z, ls[z], rs[z]); merge(x, x, z); merge(rt, x, y); return; } inline int get_kth(int rt, int k) { while (sz[ls[rt]] + 1 != k) { if (sz[ls[rt]] >= k) rt = ls[rt]; else k -= sz[ls[rt]] + 1, rt = rs[rt]; } return val[rt]; } inline int get_rank(int &rt, int val) { int x = 0, y = 0; split(rt, x, y, val - 1); int tmp = sz[x] + 1; merge(rt, x, y); return tmp; } inline int get_pre(int &rt, int valn) { int x = 0, y = 0; split(rt, x, y, valn - 1); int tmp = get_kth(x, sz[x]); merge(rt, x, y); return tmp; } inline int get_nxt(int &rt, int valn) { int x = 0, y = 0; split(rt, x, y, valn); int tmp = get_kth(y, 1); merge(rt, x, y); return tmp; } signed main() { int n = read(); add(inf); tot = 1; sz[1] = 0; rt = 1; while (n--) { int opt = read(), valn = read(); switch (opt) { case 1: insert(rt, valn); break; case 2: del(rt, valn); break; case 3: printf("%lld\n", get_rank(rt, valn)); break; case 4: printf("%lld\n", get_kth(rt, valn)); break; case 5: printf("%lld\n", get_pre(rt, valn)); break; case 6: printf("%lld\n", get_nxt(rt, valn)); break; } } return 0; } } // namespace yspm signed main() { return yspm::main(); }
NOI2015 维护数列
#include <bits/stdc++.h> #define int long long using namespace std; namespace yspm{ int st[500005], len; inline int read() { int res = 0, f = 1; char k; while (!isdigit(k = getchar())) if (k == '-') f = -1; while (isdigit(k)) res = res * 10 + k - '0', k = getchar(); return res * f; } struct node { int l, r, s, val, cov; bool lz, fl; int sum, qz, hz, zd; } t[500005]; int id, rt; int add(int v) { id = st[len--]; t[id].l = t[id].r = t[id].lz = t[id].cov = 0; t[id].s = 1; t[id].val = t[id].sum = v; t[id].qz = t[id].hz = max(0ll, v); t[id].zd = v; return id; } void push_up(int x) { if (!x) return; t[x].s = t[t[x].l].s + t[t[x].r].s + 1; t[x].sum = t[t[x].l].sum + t[t[x].r].sum + t[x].val; t[x].qz = max(max(t[t[x].l].qz, t[t[x].l].sum + t[x].val + t[t[x].r].qz), 0ll); t[x].hz = max(max(t[t[x].r].hz, t[t[x].r].sum + t[x].val + t[t[x].l].hz), 0ll); t[x].zd = max(t[x].val, t[x].val + t[t[x].l].hz + t[t[x].r].qz); if (t[x].l) t[x].zd = max(t[x].zd, t[t[x].l].zd); if (t[x].r) t[x].zd = max(t[x].zd, t[t[x].r].zd); } void Reverse(int x) { if (!x) return; swap(t[x].l, t[x].r); swap(t[x].hz, t[x].qz); t[x].lz ^= 1; } void Cover(int x, int ci) { t[x].val = t[x].cov = ci; t[x].sum = t[x].s * ci; t[x].qz = t[x].hz = max(0ll, t[x].sum); t[x].zd = max(ci, t[x].sum); t[x].fl = 1; } void push_down(int x) { if (!x) return; if (t[x].lz) { if (t[x].l) Reverse(t[x].l); if (t[x].r) Reverse(t[x].r); t[x].lz = 0; } if (t[x].fl) { if (t[x].l) Cover(t[x].l, t[x].cov); if (t[x].r) Cover(t[x].r, t[x].cov); t[x].cov = t[x].fl = 0; } } void del(int x) { if (!x) return; st[++len] = x; if (t[x].l) del(t[x].l); if (t[x].r) del(t[x].r); } void split(int x, int &L, int &R, int K) { if (x) push_down(x); if (!x) { L = R = 0; return; } if (t[t[x].l].s + 1 <= K) L = x, split(t[x].r, t[L].r, R, K - t[t[x].l].s - 1); else R = x, split(t[x].l, L, t[R].l, K); push_up(x); } void merge(int x, int y, int &root) { if (!x || !y) { root = x + y; return; } if (90000008 % (t[x].s + t[y].s) < t[x].s) push_down(x), root = x, merge(t[x].r, y, t[root].r), push_up(x); else push_down(y), root = y, merge(x, t[y].l, t[root].l), push_up(y); } int n, m; int A[500005]; int build(int l, int r) { if (l == r) { return add(A[l]); } int x, mid = (l + r) >> 1; merge(build(l, mid), build(mid + 1, r), x); return x; } char opt[10]; signed main() { n = read(), m = read(); for (int i = 1; i <= 500000; ++i) st[++len] = i; for (int i = 1; i <= n; ++i) A[i] = read(); merge(rt, build(1, n), rt); while (m--) { scanf("%s", opt); if (opt[0] == 'I') { int pos = read(), tot = read(); int x, y; split(rt, x, y, pos); for (int i = 1; i <= tot; ++i) A[i] = read(); merge(x, build(1, tot), x); merge(x, y, rt); } else if (opt[0] == 'D') { int pos = read(), tot = read(); int x, y, z; split(rt, x, y, pos - 1); split(y, y, z, tot); del(y); merge(x, z, rt); } else if (opt[0] == 'M' && opt[2] == 'K') { int pos = read(), tot = read(), ci = read(); int x, y, z; split(rt, x, y, pos - 1); split(y, y, z, tot); Cover(y, ci); merge(x, y, x); merge(x, z, rt); } else if (opt[0] == 'R') { int pos = read(), tot = read(); int x, y, z; split(rt, x, y, pos - 1); split(y, y, z, tot); Reverse(y); merge(x, y, y); merge(y, z, rt); } else if (opt[0] == 'G') { int pos = read(), tot = read(); int x, y, z; split(rt, x, y, pos - 1); split(y, y, z, tot); printf("%d\n", t[y].sum); merge(x, y, y); merge(y, z, rt); } else if (opt[0] == 'M' && opt[2] == 'X') { printf("%d\n", t[rt].zd); } } return 0; } }signed main(){return yspm::main();}
来源:https://www.cnblogs.com/yspm/p/12344831.html