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 }