题目大意:
给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖。
题解:
先%一发myy。
开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对……
然后打开题目标签……随机化……
emmmm,突然想到[bzoj 3569]DZY loves Chinese II……
随机大法好…
给每条路径随机一个权值,然后用异或来统计子树权值和,并与全集的异或和做下比较,然后就是LCT大板子……
板子写挂……wa了两遍……迷。
代码:
1 #include "bits/stdc++.h" 2 3 inline int read(){ 4 int s=0,k=1;char ch=getchar(); 5 while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar(); 6 while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar(); 7 return s*k; 8 } 9 10 using namespace std; 11 12 const int N=2e5+10; 13 14 namespace LCT{ 15 #define rev(t) (t?t->rev^=1:0) 16 #define is_root(t) (!t->fa||(t->fa->son[0]!=t&&t->fa->son[1]!=t)) 17 #define son(t) (t->fa->son[1]==t) 18 #define size(t) (t?t->size:0) 19 struct node{ 20 node *fa,*son[2]; 21 int rev,size,empty; 22 node () {fa=son[0]=son[1]=NULL,empty=rev=size=0;} 23 inline void update(){ 24 size=size(son[0])^size(son[1])^empty; 25 } 26 inline void pushdown(){ 27 if (!rev) return ; 28 rev(son[0]),rev(son[1]); 29 swap(son[0],son[1]);rev=0; 30 } 31 }tree[N/2],*tmp[N/2]; 32 33 inline void rotate(node *p){ 34 int a=son(p)^1;node *f=p->fa; 35 f->son[a^1]=p->son[a]; 36 if (p->son[a]) p->son[a]->fa=f; 37 p->fa=f->fa; 38 if (!is_root(f)) f->fa->son[son(f)]=p; 39 f->fa=p,p->son[a]=f,f->update(),p->update(); 40 } 41 42 inline void update(node *p){ 43 if (!is_root(p)) update(p->fa); 44 p->pushdown(); 45 } 46 47 inline void splay(node *p){ 48 register int pos=0; 49 for(node *t=p;;t=t->fa){ 50 tmp[++pos]=t; 51 if(is_root(t)) break; 52 } 53 for(;pos;--pos) tmp[pos]->pushdown(); 54 for(;!is_root(p);rotate(p)) 55 if(!is_root(p->fa)) rotate(son(p)==son(p->fa)?p->fa:p); 56 } 57 58 inline void access(node *p){ 59 for(node *pre=NULL;p;pre=p,p=p->fa) 60 splay(p),p->empty^=size(p->son[1])^size(pre),p->son[1]=pre,p->update(); 61 } 62 63 inline void make_root(node *x) { 64 access(x),splay(x),x->rev^=1; 65 } 66 67 inline void link(node *x,node *y) { 68 make_root(x);access(y),splay(y),x->fa=y; 69 y->empty^=size(x),y->update(); 70 } 71 72 inline void cut(node *x,node *y){ 73 make_root(x),access(y),splay(y); 74 x->fa=y->son[0]=NULL;y->update(); 75 } 76 77 inline int query(node *x,node *y) { 78 make_root(x);access(y),splay(y); 79 return size(x); 80 } 81 } 82 83 int n,m; 84 int a[N],b[N],c[N],cnt,tot; 85 86 int main (int argc, char const* argv[]){ 87 //freopen("207.in","r",stdin); 88 read(); 89 srand(201228); 90 n=read(),m=read(); 91 register int i; 92 using namespace LCT; 93 for (i=1;i<n;++i) { 94 int x=read(),y=read(); 95 link(tree+x,tree+y); 96 } 97 int type,x,y,u,v; 98 while (m--) { 99 type=read(); 100 switch (type) { 101 case 1: x=read(),y=read(),u=read(),v=read(),cut(tree+x,tree+y),link(tree+u,tree+v); 102 break; 103 case 2: x=read(),y=read(),u=rand(); 104 make_root(&tree[x]),tree[x].empty^=u,tree[x].update(), 105 make_root(&tree[y]),tree[y].empty^=u,tree[y].update(); 106 ++cnt,a[cnt]=x,b[cnt]=y,c[cnt]=u,tot^=u; 107 break; 108 case 3: x=read();u=c[x],y=b[x],x=a[x]; 109 make_root(&tree[x]),tree[x].empty^=u,tree[x].update(), 110 make_root(&tree[y]),tree[y].empty^=u,tree[y].update(); 111 tot^=u; 112 break; 113 case 4: x=read(),y=read(); 114 printf("%s ",tot==query(tree+x,tree+y)?"YES":"NO"); 115 break; 116 } 117 } 118 }