P3690 模板Link Cut Tree (动态树)
Posted mjtcn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3690 模板Link Cut Tree (动态树)相关的知识,希望对你有一定的参考价值。
P3690 【模板】Link Cut Tree (动态树)
https://www.luogu.org/problemnew/show/P3690
分析:
LCT模板
代码:
注意一下cut!
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 6 const int N = 300100; 7 8 int val[N],fa[N],ch[N][2],rev[N],sum[N],st[N],top; 9 10 inline char nc() { 11 static char buf[100000],*_p1 = buf,*_p2 = buf; 12 return _p1==_p2&&(_p2=(_p1=buf)+fread(buf,1,100000,stdin),_p1==_p2) ? EOF :*_p1++; 13 } 14 inline int read() { 15 int x = 0,f = 1;char ch=nc(); 16 for (; ch<‘0‘||ch>‘9‘; ch = nc()) if (ch == ‘-‘) f = -1; 17 for (; ch>=‘0‘&&ch<=‘9‘; ch = nc()) x = x*10+ch-‘0‘; 18 return x * f; 19 } 20 21 inline void pushup(int x) { 22 sum[x] = sum[ch[x][1]] ^ sum[ch[x][0]] ^ val[x]; 23 } 24 inline void pushdown(int x) { 25 int l = ch[x][0],r = ch[x][1]; 26 if (rev[x]) { 27 rev[l] ^= 1;rev[r] ^= 1; 28 swap(ch[x][0],ch[x][1]); 29 rev[x] ^= 1; 30 } 31 } 32 inline bool isroot(int x) { 33 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 34 } 35 inline int son(int x) { 36 return ch[fa[x]][1]==x; 37 } 38 inline void rotate(int x) { 39 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 40 if (!isroot(y)) ch[z][c] = x;fa[x] = z; 41 ch[x][!b] = y;fa[y] = x; 42 ch[y][b] = a;if (a) fa[a] = y; 43 pushup(y);pushup(x); 44 } 45 inline void splay(int x) { 46 top = 0;st[++top] = x; 47 for (int i=x; !isroot(i); i=fa[i]) st[++top] = fa[i]; 48 while (top) pushdown(st[top--]); 49 while (!isroot(x)) { 50 int y = fa[x]; 51 if (!isroot(y)) { 52 if (son(x)==son(y)) rotate(y); 53 else rotate(x); 54 } 55 rotate(x); 56 } 57 } 58 inline void access(int x) { 59 for (int last=0; x; last=x,x=fa[x]) { 60 splay(x);ch[x][1] = last;pushup(x); 61 } 62 } 63 inline void makeroot(int x) { 64 access(x); 65 splay(x); 66 rev[x] ^= 1; 67 } 68 inline int find(int x) { 69 access(x);splay(x); 70 while (ch[x][0]) x = ch[x][0]; 71 return x; 72 } 73 inline void link(int x,int y) { 74 makeroot(x); 75 fa[x] = y; 76 } 77 inline void cut(int x,int y) { 78 makeroot(x);access(y);splay(y); 79 if (fa[x] == y && !ch[x][1]) ch[y][0] = fa[x] = 0; 80 } 81 82 inline void update(int x,int y) { 83 makeroot(x);val[x] = y;pushup(x); 84 } 85 inline int query(int x,int y) { 86 makeroot(x);access(y);splay(y); 87 return sum[y]; 88 } 89 90 int main() { 91 int n = read(),m = read(),opt,x,y; 92 for (int i=1; i<=n; ++i) sum[i] = val[i] = read(); 93 while (m--) { 94 opt = read(),x = read(),y = read(); 95 if (opt==0) printf("%d ",query(x,y)); 96 else if (opt==1) { 97 if (find(x)!=find(y)) link(x,y); 98 } 99 else if (opt==2) { 100 if (find(x)==find(y)) cut(x,y); 101 } 102 else update(x,y); 103 } 104 return 0; 105 }
以上是关于P3690 模板Link Cut Tree (动态树)的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3690模板Link Cut Tree(动态树)
刷题洛谷 P3690 模板Link Cut Tree (动态树)