[UOJ207]共价大爷游长沙

Posted jefflyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[UOJ207]共价大爷游长沙相关的知识,希望对你有一定的参考价值。

如果每次加入点对$(x,y)$,就给它一个随机的权值$v$,把两个点的点权都异或$v$,查询$(x,y)$的时候,只要把$x$硬点为根,以$y$为根的子树的异或和等于当前所有的异或和,那么很大概率就是正确的(每对点刚好有一个在$y$的子树中)

所以直接用lct维护即可,因为维护了虚边信息,所以link时两边都要makeroot(不然没法更新splay里的祖先的信息),cut时不改虚边信息

splay之前一定要记得一路pushdown啊啊啊啊啊啊!

#include<stdio.h>
#include<stdlib.h>
int ch[100010][2],fa[100010],r[100010],v[100010],s[100010],vs[100010],q1[300010],q2[300010],d[300010];
#define ls ch[x][0]
#define rs ch[x][1]
void swap(int&a,int&b){a^=b^=a^=b;}
void rev(int x){
	swap(ls,rs);
	r[x]^=1;
}
bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void pushdown(int x){
	if(r[x]){
		if(ls)rev(ls);
		if(rs)rev(rs);
		r[x]=0;
	}
}
void pushup(int x){s[x]=v[x]^s[ls]^s[rs]^vs[x];}
void rot(int x){
	int y,z,f,B;
	y=fa[x];
	z=fa[y];
	f=(ch[y][0]==x);
	B=ch[x][f];
	fa[x]=z;
	fa[y]=x;
	if(B)fa[B]=y;
	ch[x][f]=y;
	ch[y][f^1]=B;
	if(ch[z][0]==y)ch[z][0]=x;
	if(ch[z][1]==y)ch[z][1]=x;
	pushup(y);
	pushup(x);
}
void gao(int x){
	if(!isrt(x))gao(fa[x]);
	pushdown(x);
}
void splay(int x){
	int y,z;
	gao(x);
	while(!isrt(x)){
		y=fa[x];
		z=fa[y];
		if(!isrt(y))rot((ch[z][0]==y&&ch[y][0]==x)||(ch[z][1]==y&&ch[y][1]==x)?y:x);
		rot(x);
	}
}
void access(int x){
	int y=0;
	while(x){
		splay(x);
		vs[x]^=s[rs];
		rs=y;
		vs[x]^=s[y];
		pushup(x);
		y=x;
		x=fa[x];
	}
}
void makert(int x){
	access(x);
	splay(x);
	rev(x);
}
void link(int x,int y){
	makert(x);
	makert(y);
	fa[x]=y;
	vs[y]^=s[x];
	pushup(y);
}
void cut(int x,int y){
	makert(y);
	access(x);
	splay(x);
	fa[y]=ls=0;
	pushup(x);
}
void modify(int x,int d){
	access(x);
	splay(x);
	v[x]^=d;
	pushup(x);
}
int query(int x,int y){
	makert(x);
	access(y);
	return vs[y]^v[y];
}
int main(){
	srand(19260817);
	int n,m,i,x,y,sum;
	scanf("%d%d%d",&i,&n,&m);
	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		link(x,y);
	}
	n=sum=0;
	while(m--){
		scanf("%d",&i);
		if(i==1){
			scanf("%d%d",&x,&y);
			cut(x,y);
			scanf("%d%d",&x,&y);
			link(x,y);
		}
		if(i==2){
			n++;
			scanf("%d%d",q1+n,q2+n);
			d[n]=x=rand()*rand();
			sum^=x;
			modify(q1[n],x);
			modify(q2[n],x);
			
		}
		if(i==3){
			scanf("%d",&x);
			modify(q1[x],d[x]);
			modify(q2[x],d[x]);
			sum^=d[x];
		}
		if(i==4){
			scanf("%d%d",&x,&y);
			puts(query(x,y)==sum?"YES":"NO");
		}
	}
}

以上是关于[UOJ207]共价大爷游长沙的主要内容,如果未能解决你的问题,请参考以下文章

UOJ207:共价大爷游长沙

uoj207 共价大爷游长沙

uoj#207 共价大爷游长沙

UOJ207 共价大爷游长沙

UOJ207共价大爷游长沙(Link-Cut Tree,随机化)

uoj#207. 共价大爷游长沙