BZOJ 4668: 冷战 并查集启发式合并/LCT

挺好想的,最简单的方法是并查集启发式合并,加暴力跳父亲。 

然而,这个代码量比较小,比较好写,所以我写了 LCT,更具挑战性。

#include <cstdio> 
#include <algorithm> 
#define N 1000004 
#define lson t[x].ch[0] 
#define rson t[x].ch[1] 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;   
int sta[N],n,m,p[N]; 
struct Node { 
	int ch[2],max,val,rev,f; 
}t[N];  
int find(int x) {
	return p[x]==x?x:p[x]=find(p[x]); 
}
int get(int x) {
	return t[t[x].f].ch[1]==x; 
}  
int isrt(int x) {
	return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x); 
}
void pushup(int x) {
	t[x].max=t[x].val; 
	t[x].max=max(max(t[lson].max,t[rson].max), t[x].max); 
}  
void mark(int x) {
	if(!x) return; 
	swap(lson, rson), t[x].rev^=1;  
}
void pushdown(int x) {
	if(t[x].rev) mark(lson), mark(rson), t[x].rev=0; 
}
void rotate(int x) {  
	int old=t[x].f,fold=t[old].f,which=get(x); 
	if(!isrt(old)) 
		t[fold].ch[t[fold].ch[1]==old]=x; 
	t[old].ch[which]=t[x].ch[which^1], t[t[old].ch[which]].f=old; 
	t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold; 
	pushup(old),pushup(x);  
} 
void splay(int x) {
	int v=0,u=x,fa; 
	for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f; 
	for(int i=v;i>=1;--i) pushdown(sta[i]); 
	for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) 
		if(t[fa].f!=u) 
			rotate(get(fa)==get(x)?fa:x);     
}
void Access(int x) {
	for(int y=0;x;y=x,x=t[x].f) { 
		splay(x),rson=y,pushup(x);        
	}
}
void makeroot(int x) {
	Access(x),splay(x),mark(x); 
} 
void split(int x,int y) {
	makeroot(x),Access(y),splay(y); 
}
void link(int x,int y) {   
	makeroot(x), makeroot(y),t[x].f=y;  
}
int main() { 
	int i,j,cc=0;  
	scanf("%d%d",&n,&m); 
	for(i=1;i<=n;++i) p[i]=i;    
	int lastans=0,tot=n; 
	for(i=1;i<=m;++i) {  
		int op,x,y; 
		scanf("%d%d%d",&op,&x,&y); 
		x^=lastans,y^=lastans; 
		if(op==0) {  
			++cc; 
			x=find(x),y=find(y); 
			if(x!=y) {
				++tot; 
				p[x]=p[y]=p[tot]=tot;  
				t[tot].val=cc;   
				link(x,tot),link(tot,y);    
			}
		}
		else { 
			int xx=find(x),yy=find(y); 
			if(xx!=yy) printf("0\n"),lastans=0; 
			else { 
				split(x,y);     
				printf("%d\n",lastans=t[y].max);   
			}
		}
	}
	return 0; 
}

  

posted @ 2019-08-29 20:54  EM-LGH  阅读(188)  评论(0编辑  收藏  举报