LCT板子68pts求查错
查看原帖
LCT板子68pts求查错
285617
黑影洞人楼主2022/8/25 16:53
#include<cstdio>
#include<algorithm>
#define N 1919810
using namespace std;
int n,m;
struct link_cut_tree{
	int ch[N][2],f[N],s[N],st[N],v[N];
	bool r[N];
	#define lc ch[x][0]
	#define rc ch[x][1]
	void pushup(int x){s[x]=s[lc]+s[rc]+v[x];}
	void rev(int x){swap(lc,rc),r[x]^=1;}
	int son(int x){return x==ch[f[x]][1];}
	int nroot(int x){return x==ch[f[x]][1]||x==ch[f[x]][0];}
	void pushdown(int x){
		if(r[x]){
			if(lc)rev(lc);
			if(rc)rev(rc);
			r[x]=0;
		}
	}
	void rotate(int x){
		int y=f[x],z=f[y],k=son(x),w=ch[x][!k];
		if(nroot(y))ch[z][son(y)]=x;
		ch[x][!k]=y;ch[y][k]=w;
		if(w)f[w]=y;
		f[y]=x,f[x]=z;
		pushup(y);
	}
	void splay(int x){
		int y=x,z=0;
		st[++z]=y;
		while(nroot(y))st[++z]=y=f[y];
		while(z)pushdown(st[z--]);
		while(nroot(x)){
			y=f[x];
			if(nroot(y))rotate(son(x)!=son(y)?x:y);
			rotate(x);
		}
		pushup(x);
	}
	void access(int x){for(int y=0;x;x=f[y=x])splay(x),rc=y,pushup(x);}
	void makeroot(int x){access(x),splay(x),rev(x);}
	int findroot(int x){
		access(x);splay(x);
		while(lc)pushdown(x=lc);
		splay(x);
		return x;
	}
	void split(int x,int y){makeroot(x),access(y),splay(y);}
	bool link(int x,int y){
		makeroot(x);
		if(findroot(y)==x)return 0;
		f[x]=y;
		return 1;
	} 
}lct;
signed main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&lct.v[i]);
	scanf("%d",&m);
	while(m--){
		char s[19];
		int a,b;
		scanf("%s%d%d",s,&a,&b);
		if(s[0]=='b')puts(lct.link(a,b)?"yes":"no");
		if(s[0]=='p')lct.v[a]=b;
		if(s[0]=='e'){
			if(lct.findroot(a)!=lct.findroot(b))puts("impossible");
			else lct.split(a,b),printf("%d\n",lct.s[b]);
		}
	}
	return 0;
}



2022/8/25 16:53
加载中...