BZOJ2843 极地旅行社 LCT

除了Cut操作之外这应该算是一道模板题了,写完之后就可以整理下来去背了……

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=30000+2;
typedef struct NODE{
	NODE *child[2],*f;
	int s,v;
	bool rev;
	NODE(){}
	NODE(NODE *_f):f(_f),rev(0){}
} *TREE;
TREE root,Null,mark[MAXN];
int N,M;
char s[10+2];

TREE NewNode(TREE f){
	TREE x=new NODE(f);
	x->child[0]=x->child[1]=Null;
	return x;
}

void Initialize(int N){
	Null=NewNode(0);
	for(int i=1;i<=N;i++) mark[i]=NewNode(Null);
}

void Pushup(TREE &x){ x->s=x->child[0]->s+x->child[1]->s+x->v;}

void Pushdown(TREE &x){
	if(x->f->child[0]==x || x->f->child[1]==x) Pushdown(x->f);
	
	if(x->rev){
		swap(x->child[0],x->child[1]);
		x->child[0]->rev^=1,x->child[1]->rev^=1;
		x->rev=0;
	}
}

void Rotate(TREE &x,bool t){
	TREE y=x->f;
	
	y->child[!t]=x->child[t],x->child[t]->f=y,x->f=y->f;
	if(y->f->child[0]==y) y->f->child[0]=x;
	if(y->f->child[1]==y) y->f->child[1]=x;
	y->f=x,x->child[t]=y;
	
	Pushup(y),Pushup(x);
}

void Splay(TREE &x){
	TREE y=x->f;
	Pushdown(x);
	while(y->child[1]==x || y->child[0]==x){
		if(x==y->child[0]){
			if(y==y->f->child[0]) Rotate(y,1);
			Rotate(x,1);
		}
		else{
			if(y==y->f->child[1]) Rotate(y,0);
			Rotate(x,0);
		}
		y=x->f;
	}
	Pushup(x);
}

void Access(TREE &x){
	TREE y=Null,z=x;
	while(z!=Null){
		Splay(z);
		z->child[1]=y;
		Pushup(z);
		y=z,z=z->f;
	}
}

void Move(TREE &x){
	Access(x),Splay(x);
	x->rev=1,Pushdown(x);
}

void Link(TREE &x,TREE &y){
	Move(x);
	x->child[0]=Null,x->f=y;
}

TREE Find(TREE &x){
	TREE y=x;
	while(y->f!=Null) y=y->f;
	return y;
}

void Update(TREE &x,int a){ Move(x),x->v=a,Pushup(x);}

int Query(TREE &x,TREE &y){
	Move(x),Access(y),Splay(y);
	Pushup(y);
	return y->s;
}

int main(){
	scanf("%d",&N);
	Initialize(N);
	for(int i=1;i<=N;i++) scanf("%d",&mark[i]->s),mark[i]->v=mark[i]->s;
	
	scanf("%d",&M);
	for(int i=1,a,b;i<=M;i++){
		scanf("%s %d %d",s,&a,&b);
		if(strstr(s,"bridge"))
			if(Find(mark[a])==Find(mark[b])) puts("no");
			else Link(mark[a],mark[b]),puts("yes");
		if(strstr(s,"penguins")) Update(mark[a],b);
		if(strstr(s,"excursion"))
			if(Find(mark[a])==Find(mark[b])) printf("%d\n",Query(mark[a],mark[b]));
			else puts("impossible");
	}

	return 0;
}


你可能感兴趣的:(BZOJ2843 极地旅行社 LCT)