LCT模板(無講解)

GreenDuck發表於2019-04-13

怎麼說呢,照著打一遍就自然理解了,再打一遍就會背了,再打一遍就會推了。

  1 // luogu-judger-enable-o2
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 const int maxn=3E5+5;
  5 int fa[maxn],son[maxn][2],val[maxn],ans[maxn],n,m,opt,x,y,z;
  6 bool tag[maxn];
  7 bool notroot(int x){return son[fa[x]][0]==x||son[fa[x]][1]==x;}
  8 void update(int x){ans[x]=ans[son[x][0]]^ans[son[x][1]]^val[x];}
  9 void pushr(int x)
 10 {
 11     swap(son[x][0],son[x][1]);
 12     tag[x]^=1;
 13 }
 14 void pushdown(int x)
 15 {
 16     if(tag[x])
 17     {
 18         if(son[x][0])pushr(son[x][0]);
 19         if(son[x][1])pushr(son[x][1]);
 20         tag[x]=0;
 21     }
 22 }
 23 void rotate(int x,int c)
 24 {
 25     int y=fa[x];
 26     fa[x]=fa[y];
 27     son[y][!c]=son[x][c];
 28     if(son[x][c])fa[son[x][c]]=y;
 29     if(notroot(y)&&son[fa[y]][0]==y)son[fa[y]][0]=x;
 30     else if(notroot(y))son[fa[y]][1]=x;
 31     son[x][c]=y;
 32     fa[y]=x;
 33     update(y);
 34     update(x);
 35 }
 36 void down(int x)
 37 {
 38     if(!notroot(x)){pushdown(x);return;}
 39     down(fa[x]);
 40     pushdown(x);
 41 }
 42 void splay(int x)
 43 {
 44     down(x);
 45     while(true)
 46     {
 47         int y=fa[x];
 48         if(!notroot(x))break;
 49         if(!notroot(y))
 50         {
 51             if(son[y][0]==x)rotate(x,1);
 52             else rotate(x,0);
 53             break;
 54         }
 55         if(son[fa[y]][0]==y)
 56         {
 57             if(son[y][0]==x)rotate(y,1),rotate(x,1);
 58             else rotate(x,0),rotate(x,1);
 59         }
 60         else
 61         {
 62             if(son[y][1]==x)rotate(y,0),rotate(x,0);
 63             else rotate(x,1),rotate(x,0);
 64         }
 65     }
 66 }
 67 void access(int x)
 68 {
 69     for(int y=0;x;y=x,x=fa[x])
 70         splay(x),son[x][1]=y,update(x);
 71 }
 72 void makeroot(int x)
 73 {
 74     access(x);
 75     splay(x);
 76     pushr(x);
 77 }
 78 int findroot(int x)
 79 {
 80     access(x);
 81     splay(x);
 82     while(son[x][0])pushdown(x),x=son[x][0];
 83     splay(x);
 84     return x;
 85 }
 86 void split(int x,int y)
 87 {
 88     makeroot(x);
 89     access(y);
 90     splay(y);
 91 }
 92 void link(int x,int y)
 93 {
 94     makeroot(x);
 95     if(findroot(y)!=x)fa[x]=y;
 96 }
 97 void cut(int x,int y)
 98 {
 99     makeroot(x);
100     if(findroot(y)==x&&fa[y]==x&&!son[y][0])
101     {
102         fa[y]=son[x][1]=0;
103         update(x);
104         update(y);
105     }
106 }
107 int main()
108 {
109     ios::sync_with_stdio(false);
110     cin>>n>>m;
111     for(int i=1;i<=n;++i)cin>>val[i];
112     while(m--)
113     {
114         cin>>opt>>x>>y;
115         if(opt==0)
116         {
117             split(x,y);
118             cout<<ans[y]<<endl;
119         }
120         else if(opt==1)link(x,y);
121         else if(opt==2)cut(x,y);
122         else
123         {
124             splay(x);
125             val[x]=y;
126         }
127     }
128     return 0;
129 }
View Code

 

相關文章