题意:求S到T中某条边是否是必然经过。(动态树)
LCT,hash去打标记,是0就是合法的。
断边的时候,把要断的边标记打在新的路径上、
#include<bits/stdc++.h> #define nrt(x) (ch[fa[x]][0]==x||ch[fa[x]][1]==x) #define pii pair<int,int> #define N 400007 using namespace std; map<pii,int> mp; inline void read(int &x){ static char c; for (c=getchar();!isdigit(c);c=getchar()); for (x=0;isdigit(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } inline int rod(){ static int x=1887415157; return x^=x<<13,x^=x>>17,x^=x<<5; } int r[N],ch[N][2],lazy[N],key[N],fa[N]; void pushdown(int x) { if (nrt(x)) pushdown(fa[x]); if (r[x]) { swap(ch[x][1],ch[x][0]); if (ch[x][1]) r[ch[x][1]]^=1; if (ch[x][0]) r[ch[x][0]]^=1; r[x]=0; } if (lazy[x]) { key[x]^=lazy[x]; if (ch[x][1]) lazy[ch[x][1]]^=lazy[x]; if (ch[x][0]) lazy[ch[x][0]]^=lazy[x]; lazy[x]=0; } } void pushup(int x){ // } void rotate(int x){ int y=fa[x],z=fa[y],l=ch[y][1]==x,r; r=l^1; if (nrt(y)) ch[z][ch[z][1]==y]=x; fa[x]=z; fa[y]=x; fa[ch[x][r]]=y; ch[y][l]=ch[x][r]; ch[x][r]=y; // pushup(y); pushup(x); } void splay(int x){ pushdown(x); while (nrt(x)){ int y=fa[x],z=fa[y]; if (nrt(y)) if (ch[y][0]==x^ch[z][0]==y) rotate(x); else rotate(y); rotate(x); } } void access(int x){ for (int y=0;x;x=fa[y=x]) { splay(x); ch[x][1]=y; //pushup(x) } } void beroot(int x){ access(x); splay(x); r[x]^=1; } void split(int x,int y) { beroot(x); access(y); splay(y); } void link(int x,int y) { beroot(x); fa[x]=y; } int ppt; int cut(int x,int y){ beroot(x); access(y); splay(y); ppt=key[ch[y][0]]; ch[y][0]=0; fa[x]=0; return ppt; } int op,n,m,x,y,tot,a[N],b[N],k[N],ans,anw,Tot,gg,xx,yy,in; signed main () { read(op); read(n); read(m); for (int i=1;i<n;i++) { read(x),read(y), link(x,i+n),link(i+n,y); if (x>y) swap(x,y); mp[pii(x,y)]=n+i; } Tot=2*n; while (m--) { read(op); if (op==1) { read(x); read(y); if (x>y) swap(x,y); in=mp[pii(x,y)]; cut(x,in); cut(y,in); gg=key[in]; read(xx); read(yy); if (xx>yy) swap(xx,yy); mp[pii(xx,yy)]=++Tot; link(xx,Tot); link(Tot,yy); split(x,y); lazy[y]^=gg; } if (op==2) { k[++tot]=rod(); read(a[tot]); read(b[tot]); ans^=k[tot]; split(a[tot],b[tot]); lazy[b[tot]]^=k[tot]; } if (op==3) { read(x); ans^=k[x]; split(a[x],b[x]); lazy[b[x]]^=k[x]; } if (op==4) { read(x); read(y); if (x>y) swap(x,y); in=mp[pii(x,y)]; beroot(in); puts(key[in]==ans?"YES":"NO"); } } return 0; }