2018.10.07【BZOJ1180】OTOCI(LCT)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82962768

传送门


解析:

L C T LCT 裸题。

就常规的 L C T LCT 操作维护链上求和就行了啊。

真是少有的让我都能写出一句话题解的题目了。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline
int getint(){
	re int num;
	re char c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
	return num;
}

inline
void outint(int a){
	static char ch[13];
	if(a==0)pc('0');
	while(a)ch[++ch[0]]=a-a/10*10,a/=10;
	while(ch[0])pc(ch[ch[0]--]^48);
}

inline char getalpha(){
	re char c;
	while(!isalpha(c=gc()));
	return c;
}

cs int N=30004;
struct Link_Cut_Tree{
	int fa[N];
	int son[N][2];
	int val[N],sum[N];
	bool tag[N];
	
	bool which(cs int &k){return son[fa[k]][1]==k;}
	bool isroot(cs int &k){return son[fa[k]][0]!=k&&son[fa[k]][1]!=k;}
	
	void pushdown(cs int &k){
		if(tag[k]){
			swap(son[k][0],son[k][1]);
			if(son[k][0])tag[son[k][0]]^=1;
			if(son[k][1])tag[son[k][1]]^=1;
			tag[k]=0;
		}
	}
	void pushup(cs int &k){
		sum[k]=sum[son[k][0]]+sum[son[k][1]]+val[k];
	}
	
	void Rotate(cs int &now){
		int Fa=fa[now],FA=fa[Fa];
		bool pos=which(now);
		if(!isroot(Fa))son[FA][which(Fa)]=now;
		fa[Fa]=now;
		fa[now]=FA;
		son[Fa][pos]=son[now][!pos];
		if(son[Fa][pos])fa[son[Fa][pos]]=Fa;
		son[now][!pos]=Fa;
		pushup(Fa);
		pushup(now);
	}
	
	void Splay(cs int &now){
		static int q[N],qn;
		q[qn=1]=now;
		for(int re Fa=now;!isroot(Fa);Fa=fa[Fa])q[++qn]=fa[Fa];
		for(int re i=qn;i;--i)pushdown(q[i]);
		for(int re Fa=fa[now];!isroot(now);Rotate(now),Fa=fa[now])
		if(!isroot(Fa))Rotate(which(now)==which(Fa)?Fa:now);
	}
	
	void access(int now){
		for(int re ch=0;now;ch=now,now=fa[now])
		Splay(now),son[now][1]=ch,pushup(now);
	}
	
	void makeroot(cs int &now){
		access(now);Splay(now);tag[now]^=1;
	}
	
	int findroot(int now){
		access(now),Splay(now);
		while(son[now][0])now=son[now][0];
		return now;
	}
	
	bool connect(int u,int v){
		makeroot(u);
		return findroot(v)==u;
	}
	
	void link(int u,int v){
		makeroot(u),fa[u]=v;
	}
	
	void update(int u,int v){
		val[u]=v;
		access(u),Splay(u);
	}
	
	int query(int u,int v){
		makeroot(u),access(v);
		Splay(v);
		return sum[v];
	}
	
}LCT;

int n,m;

signed main(){
	n=getint();
	for(int re i=1;i<=n;++i){
		int x=getint();
		LCT.update(i,x);
	}
	m=getint();
	while(m--){
		char op=getalpha();
		int u=getint(),v=getint();
		switch(op){
			case 'e':{
				if(!LCT.connect(u,v))puts("impossible");
				else outint(LCT.query(u,v)),pc('\n');
				break;
			}
			case 'b':{
				if(LCT.connect(u,v))puts("no");
				else puts("yes"),LCT.link(u,v);
				break;
			}
			case 'p':{
				LCT.update(u,v);
				break;
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/82962768