bzoj4825
LCT
昨天调试一天没出来,今天推倒重写还是gg了,内心崩溃照着源代码抄,结果发现自己把原树fa和splay的fa一起维护,各种re。。。
其实我们手玩一下,发现其实树的形态变化很小,那么就可以用lct维护了,查询就是相当于查询点到root的点权和,点权为1
删除什么的手画一下就行了
然后我们要用一个数组维护一下原树形态,因为splay是二叉树,可以很方便地维护树的形态,但是一般的树比较麻烦,因为删除儿子什么的的确很烦。这些信息不能再lct上维护,因为lct上fa会变化,里面的fa是splay的fa,不是原树的fa,就破坏了原树形态,所以不能这样维护
然后就是lct各种操作。。。几个月没写都忘了。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N = 100010, inf = 1000000010; namespace IO { const int Maxlen = N * 30; char buf[Maxlen], *C = buf; int Len; inline void read_in() { Len = fread(C, 1, Maxlen, stdin); buf[Len] = '\0'; } inline void fread(int &x) { x = 0; int f = 1; while (*C < '0' || '9' < *C) { if(*C == '-') f = -1; ++C; } while ('0' <= *C && *C <= '9') x = (x << 1) + (x << 3) + *C - '0', ++C; x *= f; } inline void read(int &x) { x = 0; int f = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + c - '0'; c = getchar(); } x *= f; } inline void read(long long &x) { x = 0; long long f = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 1ll) + (x << 3ll) + c - '0'; c = getchar(); } x *= f; } } using namespace IO; int m, opt, cnt, key, root; set<pair<int, int> > s; namespace LCT { int st[N]; struct node { int size, l, r, c[2], fa, tag; } t[N]; inline bool wh(int x) { return t[t[x].fa].c[1] == x; } inline void update(int x) { t[x].size = t[t[x].c[0]].size + t[t[x].c[1]].size + 1; } inline bool isroot(int x) { return t[t[x].fa].c[0] != x && t[t[x].fa].c[1] != x; } inline void pushdown(int x) { if(!t[x].tag) return; swap(t[x].c[0], t[x].c[1]); t[t[x].c[0]].tag ^= 1; t[t[x].c[1]].tag ^= 1; t[x].tag ^= 1; } inline void up(int x) { int top = 0; st[++top] = x; while(!isroot(x)) { x = t[x].fa; st[++top] = x; } for(int i = top; i; --i) pushdown(st[i]); } inline void rotate(int x) { int y = t[x].fa, z = t[y].fa, w = wh(x); t[x].fa = z; if(!isroot(y)) t[z].c[wh(y)] = x; t[y].c[w] = t[x].c[w ^ 1]; t[t[x].c[w ^ 1]].fa = y; t[x].c[w ^ 1] = y; t[y].fa = x; update(y); update(x); } inline void splay(int x) { up(x); while(!isroot(x)) { if(!isroot(t[x].fa)) rotate(wh(x) == wh(t[x].fa) ? t[x].fa : x); rotate(x); } } inline void access(int u) { for(int f = 0; u; f = u, u = t[u].fa) { splay(u); t[u].c[1] = f; update(u); } } inline void rever(int u) { access(u); splay(u); t[u].tag ^= 1; } inline void link(int u, int v) { if(!u || !v) return; rever(u); t[u].fa = v; } inline void cut(int u, int v) { if(!u || !v) return; rever(u); access(v); splay(v); t[v].c[0] = t[u].fa = 0; update(v); } inline void que(int u) { rever(root); access(u); splay(u); printf("%d\n", t[u].size); } } using LCT :: link; using LCT :: cut; using LCT :: que; struct info { int l, r, fa; } t[N]; inline void insert(int key) { pair<int, int> o = make_pair(key, ++cnt); set<pair<int, int> > :: iterator it1, it2; it1 = it2 = s.insert(o).first; int u = 0, v = 0, x = cnt; if(it1 != s.begin()) u = (--it1) -> second; if(++it2 != s.end()) v = it2 -> second; if(u == 0 && v == 0) root = x; else if(v && t[v].l == 0) { t[v].l = x; t[x].fa = v; link(v, cnt); } else if(u && t[u].r == 0) { t[u].r = x; t[x].fa = u; link(u, cnt); } que(cnt); } inline void splay_min() { int u = s.begin() -> second, r = t[u].r, p = t[u].fa; que(u); if(u == root) return; cut(u, p); cut(u, r); link(p, r); link(u, root); t[u].r = root; t[root].fa = u; t[r].fa = p; t[p].l = r; root = u; } inline void splay_max() { set<pair<int, int> > :: iterator it = s.end(); int u = (--it) -> second, l = t[u].l, p = t[u].fa; que(u); if(u == root) return; cut(u, p); cut(u, l); link(p, l); link(u, root); t[u].l = root; t[root].fa = u; t[l].fa = p; t[p].r = l; root = u; } inline void del_min() { set<pair<int, int> > :: iterator it = s.begin(); int u = it -> second, r = t[u].r, p = t[u].fa; que(u); if(u == root) { cut(u, r); t[r].fa = 0; root = r; } else { cut(u, p); cut(u, r); link(p, r); t[r].fa = p; t[p].l = r; } s.erase(it); } inline void del_max() { set<pair<int, int > > :: iterator it = s.end(); int u = (--it) -> second, l = t[u].l, p = t[u].fa; que(u); if(u == root) { cut(u, l); t[l].fa = 0; root = l; } else { cut(u, p); cut(u, l); link(p, l); t[l].fa = p; t[p].r = l; } s.erase(it); } int main() { // read_in(); read(m); while(m--) { read(opt); if(opt == 1) read(key), insert(key); if(opt == 2) splay_min(); if(opt == 3) splay_max(); if(opt == 4) del_min(); if(opt == 5) del_max(); } return 0; }