P3690 【模板】Link Cut Tree (动态树)

P3690 【模板】Link Cut Tree (动态树)

https://www.luogu.org/problemnew/show/P3690

 

分析:

  LCT模板

 

代码:

注意一下cut!

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 
 5 char buf[100000],*_p1 = buf,*_p2 = buf;
 6 #define nc() (_p1==_p2&&(_p2=(_p1=buf)+fread(buf,1,100000,stdin),_p1==_p2) ? EOF :*_p1++) 
 7 inline int read() {
 8     int x=0,f=1;char ch=nc();for(;!isdigit(ch);ch=nc())if(ch=='-')f=-1;
 9     for (;isdigit(ch);ch=nc())x=x*10+ch-'0';return x*f;
10 }
11 
12 const int N = 300100;
13 
14 int val[N],fa[N],ch[N][2],rev[N],sum[N],sk[N],Top;
15 
16 inline void pushup(int x) {
17     sum[x] = sum[ch[x][0]] ^ sum[ch[x][1]] ^ val[x];
18 }
19 inline void pushdown(int x) {
20     if (rev[x]) {
21         rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1;
22         swap(ch[x][0], ch[x][1]);
23         rev[x] ^= 1;
24     }
25 }
26 inline bool isroot(int x) {
27     return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
28 }
29 inline int son(int x) {
30     return x == ch[fa[x]][1];
31 }
32 inline void rotate(int x) {
33     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
34     if (!isroot(y)) ch[z][c] = x;fa[x] = z;
35     ch[x][!b] = y;fa[y] = x;
36     ch[y][b] = a;if (a) fa[a] = y;
37     pushup(y);pushup(x);
38 }
39 inline void splay(int x) {
40     sk[Top = 1] = x;
41     for (int i=x; !isroot(i); i=fa[i]) sk[++Top] = fa[i];
42     while (Top) pushdown(sk[Top--]);
43     while (!isroot(x)) {
44         int y = fa[x];
45         if (isroot(y)) rotate(x);
46         else {
47             if (son(x) == son(y)) rotate(y), rotate(x);
48             else rotate(x), rotate(x);
49         }
50     }
51 }
52 inline void access(int x) {
53     for (int last=0; x; last=x, x=fa[x]) {
54         splay(x); ch[x][1] = last; pushup(x);
55     }
56 }
57 inline void makeroot(int x) {
58     access(x); splay(x); rev[x] ^= 1;
59 }
60 inline int find(int x) {
61     access(x); splay(x); 
62     while (ch[x][0]) x = ch[x][0];
63     return x;
64 }
65 inline void link(int x,int y) {
66     makeroot(x); 
67     fa[x] = y;
68 }
69 inline void cut(int x,int y) {
70     makeroot(x); access(y); splay(y);
71     if (fa[x] == y && !ch[x][1]) fa[x] = ch[y][0] = 0;
72 }
73 inline void update(int x,int y) {
74     makeroot(x);val[x] = y;pushup(x);
75 }
76 inline int query(int x,int y) {
77     makeroot(x);access(y);splay(y);
78     return sum[y];
79 }
80 int main() {
81     int n = read(),m = read(),opt,x,y;
82     for (int i=1; i<=n; ++i) sum[i] = val[i] = read();
83     while (m--) {
84         opt = read(),x = read(),y = read();
85         if (opt==0) printf("%d\n",query(x,y));
86         else if (opt==1) {
87             if (find(x)!=find(y)) link(x,y);
88         }
89         else if (opt==2) {
90             if (find(x)==find(y)) cut(x,y);
91         }
92         else update(x,y);
93     }
94     return 0;
95 }

 

posted @ 2018-07-12 14:47  MJT12044  阅读(281)  评论(0编辑  收藏  举报