【LCT】BJOI2014大融合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34454069/article/details/88954525

分析:

比较简单的LCT维护子树板子题(set都用不着…)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef long long ll;
struct node *NIL;
struct node{
	node *ch[2],*fa;
	int sum,rev,val;
	bool Isroot(){
		return fa==NIL||(fa->ch[1]!=this&&fa->ch[0]!=this);
	}
	bool Dir(){
		return fa->ch[1]==this;	
	}
	void Setchild(node *x,int d){
		ch[d]=x;
		if(x!=NIL)
			x->fa=this;	
	}
	void pushup(){
		sum=ch[0]->sum+ch[1]->sum+val;
	}
	void pushdown(){
		if(rev){
			swap(ch[0],ch[1]);
			if(ch[0]!=NIL)
				ch[0]->rev^=1;
			if(ch[1]!=NIL)
				ch[1]->rev^=1;
			rev=0;
		}
	}
}Tree[MAXN];
void Rotate(node *x){
	node *y=x->fa;
	y->pushdown(),x->pushdown();
	int d=x->Dir();
	if(y->Isroot())
		x->fa=y->fa;
	else
		y->fa->Setchild(x,y->Dir());
	y->Setchild(x->ch[!d],d);
	x->Setchild(y,!d);
	y->pushup();	
}
void Splay(node *x){
	x->pushdown();
	while(x->Isroot()==0){
		node *y=x->fa;
		if(y->Isroot())
			Rotate(x);
		else{
			if(x->Dir()==y->Dir())
				Rotate(y);
			else
				Rotate(x);
			Rotate(x);	
		}
	}
	x->pushup();
}
void Access(node *x){
	node *c=NIL;
	while(x!=NIL){
		Splay(x);
		x->val-=c->sum;
		x->val+=x->ch[1]->sum;
		x->Setchild(c,1);
		x->pushup();
		c=x;
		x=x->fa;
	}
}
void MakeRoot(node *x){
	Access(x);
	Splay(x);
	x->rev^=1;
}
void Link(node *x,node *y){
	MakeRoot(x);
	Access(y);
	Splay(y);
	x->fa=y;
	y->val+=x->sum;
	y->sum+=x->sum;
}	
ll Query(node *x,node *y){
	MakeRoot(x);
	Access(y);
	Splay(y);
	ll A=y->ch[1]->sum+y->val;
	ll B=x->sum;
	return A*B;	
}
void init(){
	NIL=Tree;
	NIL->ch[0]=NIL->ch[1]=NIL->fa=NIL;	
}
void Newnode(node *x,int val){
	x->sum=x->val=val;	
	x->ch[0]=x->ch[1]=x->fa=NIL;
}
char s[10];
int main(){
	init();
	int n,m,u,v;
	SF("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		Newnode(Tree+i,1);
	for(int i=1;i<=m;i++){
		SF("%s",s);
		SF("%d%d",&u,&v);
		if(s[0]=='A')
			Link(Tree+u,Tree+v);
		else
			PF("%lld\n",Query(Tree+u,Tree+v));
//		for(int i=1;i<=n;i++)
//			PF("%d %d %d %d,%d\n",Tree[i].val,Tree[i].sum,Tree[i].fa-Tree,Tree[i].ch[0]-Tree,Tree[i].ch[1]-Tree);
//		PF("------------\n");
	}
}

猜你喜欢

转载自blog.csdn.net/qq_34454069/article/details/88954525