uoj207共价大爷游长沙

话说我可能还没有调出魔法森林呢。。。说好的lct第一题呢。。。

又是一个随机化的方法,毕竟又是判定性的问题

上次是判断无向图联通

这次是判断一些路径是否经过一条定边

若把路径上的边全部异或上一个路径的权值

只要判断这条边的权值是否是所有路径的权值异或和就没了

lct维护链上异或和就好了

 

  1 #include<bits/stdc++.h>
  2 #define MAXN 100010
  3 #define MAXM 300010
  4 #define ll long long
  5 using namespace std;
  6 int fa[MAXN],son[MAXN][2],siz[MAXN],pe[MAXN],ne[MAXN],fe[MAXN],le[MAXN],sum[MAXN],ch[MAXN];
  7 int val[MAXN+MAXM];
  8 bool rev[MAXN];
  9 int st[MAXN],tp;
 10 int v[MAXM],v1[MAXM],v2[MAXM],cnt;
 11 int n,m;
 12 int S;
 13 int tot;
 14 int rd()
 15 {
 16     if(RAND_MAX==32767) return (rand()<<15)+rand();
 17     else return rand();
 18 } 
 19 bool ir(int x)
 20 {
 21     return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
 22 }
 23 void ud(int x)
 24 {
 25     siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;
 26     sum[x]=0;
 27     fe[x]=pe[x];
 28     le[x]=ne[x];
 29     if(son[x][0])
 30     {
 31         sum[x]^=sum[son[x][0]]^val[pe[x]];
 32         fe[x]=fe[son[x][0]];
 33     }
 34     if(son[x][1])
 35     {
 36         sum[x]^=sum[son[x][1]]^val[ne[x]];
 37         le[x]=le[son[x][1]];
 38     }
 39 }
 40 void torev(int x)
 41 {
 42     if(!x)
 43         return;
 44     swap(son[x][0],son[x][1]);
 45     swap(pe[x],ne[x]);
 46     swap(fe[x],le[x]);
 47     rev[x]^=1;
 48 }
 49 void toch(int x,int y)
 50 {
 51     if(!x)
 52         return;
 53     if(siz[x]&1^1)
 54         sum[x]^=y;
 55     if(son[x][0])
 56         val[pe[x]]^=y;
 57     if(son[x][1])
 58         val[ne[x]]^=y;
 59     ch[x]^=y;
 60 }
 61 void pd(int x)
 62 {
 63     if(rev[x])
 64     {
 65         torev(son[x][0]);
 66         torev(son[x][1]);
 67         rev[x]=0;
 68     }
 69     if(ch[x])
 70     {
 71         toch(son[x][0],ch[x]);
 72         toch(son[x][1],ch[x]);
 73         ch[x]=0;
 74     }
 75 }
 76 void cot(int x,int y,int z)
 77 {
 78     if(x)
 79         fa[x]=y;
 80     if(y)
 81         son[y][z]=x;
 82 }
 83 void rot(int x,bool z)
 84 {
 85     int xx=fa[x],xxx=fa[xx];
 86     cot(son[x][z],xx,z^1);
 87     if(ir(xx))
 88         fa[x]=xxx;
 89     else
 90         cot(x,xxx,son[xxx][1]==xx);
 91     cot(xx,x,z);
 92     ud(xx);
 93 }
 94 void apd(int x)
 95 {
 96     int i;
 97     st[++tp]=x;
 98     for(i=x;!ir(i);i=fa[i])
 99         st[++tp]=fa[i];
100     for(;tp;tp--)
101         pd(st[tp]);
102 }
103 void splay(int x)
104 {
105     apd(x);
106     while(!ir(x))
107     {
108         int xx=fa[x],xxx=fa[xx];
109         if(ir(xx))
110             rot(x,son[xx][0]==x);
111         else
112         {
113             bool z=son[xxx][0]==xx;
114             if(son[xx][z]==x)
115             {
116                 rot(x,z^1);
117                 rot(x,z);
118             }
119             else
120             {
121                 rot(xx,z);
122                 rot(x,z);
123             }
124         }
125     }
126     ud(x);
127 }
128 void acs(int x)
129 {
130     int t=0;
131     while(x)
132     {
133         splay(x);
134         son[x][1]=t;
135         ne[x]=fe[t];
136         ud(x);
137         t=x;
138         x=fa[x];
139     }
140 }
141 void reboot(int x)
142 {
143     acs(x);
144     splay(x);
145     torev(x);
146 }
147 void link(int x,int y,int z)
148 {
149     reboot(x);
150     fa[x]=y;
151     pe[x]=z;
152 }
153 void pick(int x,int y)
154 {
155     reboot(y);
156     acs(x);
157     splay(x);
158 }
159 void cut(int x,int y)
160 {
161     pick(x,y);
162     son[x][0]=fa[y]=0;
163     pe[x]=fe[x]=ne[y]=le[y]=0;
164     ud(x);
165     ud(y);
166 }
167 int ask(int x,int y)
168 {
169     pick(x,y);
170     return sum[x];
171 }
172 void change(int x,int y,int z)
173 {
174     pick(x,y);
175     toch(x,z);
176 }
177 int main()
178 {
179     int i,o,x,y,z,xx,yy;
180     srand(time(0));
181     scanf("%*d%d%d",&n,&m);
182     for(i=1;i<=n;i++)
183         siz[i]=1;
184     for(i=1;i<n;i++)
185     {
186         scanf("%d%d",&x,&y);
187         link(x,y,++tot);
188     }
189     while(m--)
190     {
191         int cmd;
192         scanf("%d",&cmd);
193         if(cmd==1)
194         {
195             scanf("%d%d%d%d",&x,&y,&xx,&yy);
196             z=ask(x,y);
197             cut(x,y);
198             link(xx,yy,++tot);
199             change(x,y,z);
200         }
201         if(cmd==2)
202         {
203             cnt++;
204             scanf("%d%d",&v1[cnt],&v2[cnt]);
205             v[cnt]=rd();
206             S^=v[cnt];
207             change(v1[cnt],v2[cnt],v[cnt]);
208         }
209         if(cmd==3)
210             scanf("%d",&x),
211             S^=v[x],
212             change(v1[x],v2[x],v[x]);
213         if(cmd==4)
214             scanf("%d%d",&x,&y),
215             puts(ask(x,y)==S?"YES":"NO");
216     }
217     return 0;
218 }

 

posted @ 2017-08-23 15:15  汪立超  阅读(310)  评论(0编辑  收藏  举报