【LG5055】可持久化文藝平衡樹
阿新 • • 發佈:2018-12-30
ins fhq and sdi sum urn 平衡樹 inline ref
【LG5055】可持久化文藝平衡樹
題面
洛谷
題解
終於不可以用\(Trie\)水了。。。
和普通的\(FHQ\;treap\)差不多
註意一下\(pushdown\)、\(split\)要新開節點
代碼
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <ctime> using namespace std; inline int gi() { register int data = 0, w = 1; register char ch = 0; while (!isdigit(ch) && ch != '-') ch = getchar(); if (ch == '-') w = -1, ch = getchar(); while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); return w * data; } const int MAX_N = 2e5 + 5; struct Node { int ls, rs, pri, val, size; long long sum; bool rev; } t[MAX_N << 6]; int rub[MAX_N << 6], cur, rubtop, rt[MAX_N]; inline int newNode(int v = 0) { int o = rubtop ? rub[rubtop--] : ++cur; t[o].val = t[o].sum = v; t[o].pri = rand(); t[o].size = 1; t[o].ls = t[o].rs = t[o].rev = 0; return o; } inline int clone(int y) { int x = rubtop ? rub[rubtop--] : ++cur; t[x] = t[y]; return x; } inline void pushup(int o) { t[o].size = t[t[o].ls].size + t[t[o].rs].size + 1; t[o].sum = t[t[o].ls].sum + t[t[o].rs].sum + t[o].val; } inline void pushdown(int o) { if (!t[o].rev) return ; swap(t[o].ls, t[o].rs); if (t[o].ls) t[o].ls = clone(t[o].ls), t[t[o].ls].rev ^= 1; if (t[o].rs) t[o].rs = clone(t[o].rs), t[t[o].rs].rev ^= 1; t[o].rev = 0; } void split(int o, int k, int &ls, int &rs) { if (!o) ls = rs = 0; else { pushdown(o); if (k <= t[t[o].ls].size) rs = clone(o), split(t[rs].ls, k, ls, t[rs].ls), pushup(rs); else ls = clone(o), split(t[ls].rs, k - t[t[o].ls].size - 1, t[ls].rs, rs), pushup(ls); } } int merge(int x, int y) { if (!(x && y)) return x ^ y; if (t[x].pri < t[y].pri) { pushdown(y); t[y].ls = merge(x, t[y].ls); pushup(y); return y; } else { pushdown(x); t[x].rs = merge(t[x].rs, y); pushup(x); return x; } } void insert(int &o, int k, int v) { int x, y; split(o, k, x, y); o = merge(merge(x, newNode(v)), y); } void erase(int &o, int pos) { int x, y, z; split(o, pos, x, z); split(x, pos - 1, x, y); rub[++rubtop] = y; o = merge(x, z); } void reverse(int &o, int l, int r) { int x, y, z; split(o, r, x, z); split(x, l - 1, x, y); t[y].rev ^= 1; o = merge(merge(x, y), z); } long long query(int &o, int l, int r) { int x, y, z; split(o, r, x, z); split(x, l - 1, x, y); long long res = t[y].sum; o = merge(merge(x, y), z); return res; } long long ans = 0; int N; int main () { srand(19260817); N = gi(); for (int i = 1; i <= N; i++) { int v = gi(), op = gi(); rt[i] = rt[v]; if (op == 1) { int k = gi() ^ ans, val = gi() ^ ans; insert(rt[i], k, val); } else if (op == 2) { int k = gi() ^ ans; erase(rt[i], k); } else if (op == 3) { int l = gi() ^ ans, r = gi() ^ ans; reverse(rt[i], l, r); } else { int l = gi() ^ ans, r = gi() ^ ans; printf("%lld\n", ans = query(rt[i], l, r)); } } return 0; }
【LG5055】可持久化文藝平衡樹