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\n",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 }

猜你喜欢

转载自www.cnblogs.com/mjtcn/p/9299399.html
今日推荐