[模板]動態樹 Link-cut Tree
阿新 • • 發佈:2018-12-16
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define reg register inline int read() { int res = 0;char ch = getchar();bool fu = 0; while(!isdigit(ch)) fu |= (ch == '-'), ch = getchar(); while(isdigit(ch)) res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar(); return fu ? - res : res; } #define int long long namespace BriMon { #define N 300005 int n, m; int val[N], ch[N][2], fa[N], rev[N], tr[N]; inline int whois(int x) {return ch[fa[x]][1] == x;} inline int isr(int x) {return ch[fa[x]][0] != x and ch[fa[x]][1] != x;} inline void upd(int x) {tr[x] = tr[ch[x][0]] ^ tr[ch[x][1]] ^ val[x];} inline void rever(int x) {rev[x] ^= 1, swap(ch[x][0], ch[x][1]);} inline void pushdown(int x) { if (rev[x]) { rev[x] = 0; if (ch[x][0]) rever(ch[x][0]); if (ch[x][1]) rever(ch[x][1]); } } inlinevoid pd(int x) {if (!isr(x)) pd(fa[x]);pushdown(x);} inline void rot(int x) { int y = fa[x], z = fa[y], d = whois(x); if (!isr(y)) ch[z][whois(y)] = x;fa[x] = z; ch[y][d] = ch[x][d ^ 1], fa[ch[x][d ^ 1]] = y; ch[x][d ^ 1] = y, fa[y] = x; upd(y), upd(x); } inline void splay(int x) { pd(x); for ( ; !isr(x) ; rot(x)) if (!isr(fa[x])) rot(ch[fa[fa[x]]][1] == fa[x] and ch[fa[x]][1] == x ? fa[x] : x); } inline void access(int x) { for (reg int y = 0 ; x ; y = x, x = fa[x]) splay(x), ch[x][1] = y, upd(x); } inline void makr(int x) { access(x), splay(x); rever(x); } inline int findr(int x) { access(x), splay(x); while(ch[x][0]) pushdown(x), x = ch[x][0]; return x; } inline void link(int x, int y) {makr(x), fa[x] = y;} inline void cut(int x, int y) { makr(x); if (findr(y) != x or fa[x] != y or ch[x][1]) return ; fa[x] = 0, ch[y][0] = 0, upd(y); } inline void split(int x, int y) { makr(x), access(y), splay(y); } int main() { n = read(), m = read(); for (reg int i = 1 ; i <= n ; i ++) val[i] = read(); while(m --) { int opt = read(), x = read(), y = read(); if (opt == 0) split(x, y), printf("%lld\n", tr[y]); else if (opt == 1) {if (findr(x) != findr(y)) link(x, y);} else if (opt == 2) {if (findr(x) == findr(y)) cut(x, y);} else splay(x), val[x]=y; } return 0; } } int zZh = BriMon :: main(); signed main() {return 0;}