【洛谷 P3690】 【模板】Link Cut Tree (動態樹)
阿新 • • 發佈:2019-01-28
shu root org www getch .com std void swap
題目鏈接
\(RT\)。
FlashHu巨佬的博客
#include <cstdio> #define R register int #define I inline void #define lc c[x][0] #define rc c[x][1] const int MAXN = 300010; inline int read(){ int s = 0, w = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * w; } int f[MAXN], c[MAXN][2], v[MAXN], s[MAXN], st[MAXN], tag[MAXN]; inline int nroot(R x){ return c[f[x]][0] == x || c[f[x]][1] == x; } I pushup(R x){ s[x] = s[lc] ^ s[rc] ^ v[x]; } I swap(R x){ lc ^= rc; rc = lc ^ rc; lc ^= rc; tag[x] ^= 1; } I pushdown(R x){ if(tag[x]){ swap(lc); swap(rc); tag[x] = 0; } } I rotate(R x){ R y = f[x], z = f[y], k = c[y][1] == x, w = c[x][!k]; if(nroot(y)) c[z][c[z][1] == y] = x; c[x][!k] = y; c[y][k] = w; f[y] = x; f[x] = z; if(w) f[w] = y; pushup(y); } I splay(R x){ R y = x, z = 0; st[++z] = y; while(nroot(y)) st[++z] = y = f[y]; while(z) pushdown(st[z--]); while(nroot(x)){ y = f[x]; z = f[y]; if(nroot(y)) (c[z][1] == y) ^ (c[y][1] == x) ? rotate(x) : rotate(y); rotate(x); } pushup(x); } I access(R x){ for(R y = 0; x; x = f[y = x]){ splay(x); rc = y; pushup(x); } } I makeroot(R x){ access(x); splay(x); swap(x); } inline int findroot(R x){ makeroot(x); splay(x); while(lc){ x = lc; pushdown(x); } splay(x); return x; } I split(R x, R y){ makeroot(x); access(y); splay(y); } I link(R x, R y){ makeroot(x); if(findroot(y) != x) f[x] = y; } I cut(R x, R y){ split(x, y); if(c[y][0] == x){ f[x] = c[y][0] = 0; pushup(y); } } int n, m, opt, a, b; int main(){ n = read(); m = read(); for(R i = 1; i <= n; ++i) v[i] = read(); while(m--){ opt = read(); a = read(); b = read(); switch(opt){ case 0 : split(a, b); printf("%d\n", s[b]); break; case 1 : link(a, b); break; case 2 : cut(a, b); break; case 3 : splay(a); v[a] = b; break; } } return 0; }
【洛谷 P3690】 【模板】Link Cut Tree (動態樹)