【BZOJ】【P3786】【星系探索】【題解】【(僞)Top tree】

傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=3786

寫(chao)吐了

等明天寫完sone1再發題解

Code:

#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
int getint(){
	int res=0;char c=getchar();
	while(!isdigit(c))c=getchar();
	while(isdigit(c))res=res*10+c-'0',c=getchar();
	return res;
}
int n;
struct info{
	LL sum;int size;
	info(LL _sum=0,int _size=1){sum=_sum;size=_size;}
	void clear(){sum=0;size=1;}
	void deb(){printf("sum:%d size:%d",(int)sum,size);}
};
struct flag{
	LL add;
	flag(LL _add=0){add=_add;}
	bool empty(){return !add;}
	void clear(){add=0;}
};
info operator+(const info &ls,const info &rs){
	return info(ls.sum+rs.sum,ls.size+rs.size);
}
info operator+(const info &ls,const flag &rs){
	return ls.size?info(ls.sum+(LL)rs.add*ls.size,ls.size):ls;
}
flag operator+(const flag &ls,const flag &rs){
	return flag(ls.add+rs.add);
}
struct node{
	node *c[4],*f;
	flag Cha,All;
	info cha,sub,all;
	bool rev,inr;
	LL val;
	node(){
		memset(c,0,sizeof c);f=0;
		Cha.clear();All.clear();cha.clear();sub.clear();all.clear();
		rev=inr=0;val=0;
	}
	void makerev(){rev^=1;swap(c[0],c[1]);}
	void makec(const flag &a){
		Cha=Cha+a;cha=cha+a;val=val+a.add;
		all=cha+sub;
	}
	void makes(const flag &a,bool _=1){
		All=All+a;all=all+a;sub=sub+a;
		if(_)makec(a);
	}
	void rz(){
		cha.clear();sub=info(0,0);all.clear();
		if(!inr)cha=all=info(val);
		rep(i,0,2)if(c[i])cha=cha+c[i]->cha,sub=sub+c[i]->sub;
		rep(i,0,4)if(c[i])all=all+c[i]->all;
		rep(i,2,4)if(c[i])sub=sub+c[i]->all;
	}
	void pd(){
		if(rev){
			if(c[0])c[0]->makerev();
			if(c[1])c[1]->makerev();
			rev=0;
		}
		if(!Cha.empty()){
			rep(i,0,2)if(c[i])c[i]->makec(Cha);
			Cha.clear();
		}
		if(!All.empty()){
			rep(i,0,4)if(c[i])c[i]->makes(All,i>=2);
			All.clear();
		}
	}
	node *C(int i){if(c[i])c[i]->pd();return c[i];}
	bool d(int ty){return f->c[ty+1]==this;}
	int D(){rep(i,0,4)if(f->c[i]==this)return i;}
	void sets(node *x,int d){if(x)x->f=this;c[d]=x;}
	bool rt(int ty){
		if(ty==0)return !f||(f->c[0]!=this&&f->c[1]!=this);
		else return !f||!f->inr||!inr;
	}
}nd[maxn*2],*cur=nd+maxn,*pool[maxn],**Cur=pool;
int _cnt;
node *newnode(){
	_cnt++;
	node *x=(Cur==pool)?cur++:*(--Cur);
	rep(i,0,4)x->c[i]=0;x->f=0;
	x->all=info(0,0);
	x->cha=info(0,0);
	x->sub=info(0,0);
	x->inr=1;x->rev=0;x->val=0;
	return x;	
}
int max(long long x,int y){return max(int(x),y);}
void deb(node *x){
	if(!x)return;
	printf("id:%d f:%d c[0]:%d c[1]:%d c[2]:%d c[3]:%d inr:%d val:%d",
	max(x-nd,-1),max(x->f-nd,-1),max(x->c[0]-nd,-1),max(x->c[1]-nd,-1),max(x->c[2]-nd,-1)
	,max(x->c[3]-nd,-1),x->inr,int(x->val));
	printf(" cha:");x->cha.deb();
	printf(" sub:");x->sub.deb();
	printf(" all:");x->all.deb();
	puts("");
}
void deb(){
	for(int i=1;i<=n;i++)deb(nd+i);
	for(int i=maxn;i<maxn+_cnt;i++)deb(nd+i);puts("");
}
void dele(node *x){*(Cur++)=x;}
void rot(node *x,int ty){
	node *p=x->f;int d=x->d(ty);
	if(!p->f)x->f=0;else p->f->sets(x,p->D());
	p->sets(x->c[!d+ty],d+ty);x->sets(p,!d+ty);p->rz();
}
void splay(node *x,int ty=0){
	while(!x->rt(ty)){
		if(x->f->rt(ty))rot(x,ty);
		else if(x->d(ty)==x->f->d(ty))rot(x->f,ty),rot(x,ty);
		else rot(x,ty),rot(x,ty);
	}x->rz();
}
void add(node *u,node *w){
	w->pd();
	rep(i,2,4)if(!w->c[i]){w->sets(u,i);return;}
	node *x=newnode(),*v;
	for(v=w;v->c[2]->inr;v=v->C(2));
	x->sets(v->c[2],2);x->sets(u,3);
	v->sets(x,2);splay(x,2);	
}
void del(node *w){
	if(w->f->inr){
		w->f->f->sets(w->f->c[5-w->D()],w->f->D());
		dele(w->f);splay(w->f->f,2);
	}else w->f->sets(0,w->D());
	w->f=0;
}
void access(node *w){
	static node *sta[maxn];
	static int top=0;
	node *v=w,*u;
	for(u=w;u;u=u->f)sta[top++]=u;
	while(top)sta[--top]->pd();
	splay(w);
	if(w->c[1])u=w->c[1],w->c[1]=0,add(u,w),w->rz();
	while(w->f){
		for(u=w->f;u->inr;u=u->f);
		splay(u);
		if(u->c[1])w->f->sets(u->c[1],w->D()),splay(w->f,2);
		else del(w);
		u->sets(w,1);
		(w=u)->rz();
	}splay(v);
}
void makert(node *x){
	access(x);x->makerev();
}
node *findp(node *u){
	access(u);u=u->C(0);
	while(u&&u->c[1])u=u->C(1);
	return u;
}
node *findr(node *u){for(;u->f;u=u->f);return u;}
node* cut(node *u){
	node *v=findp(u);
	if(v)access(v),del(u),v->rz();
	return v;
}
void link(node *u,node *v) {
	node* p=cut(u);
	if(findr(u)!=findr(v))p=v;
	if(p)access(p),add(u,p),p->rz();
}
int main(){
	n=getint();
	static int fa[maxn];
	rep(i,2,n+1)scanf("%d",&fa[i]);
	rep(i,1,n+1)scanf("%d",&nd[i].val),nd[i].rz();
	rep(i,2,n+1){
		makert(nd+fa[i]);
		link(nd+i,nd+fa[i]);
	}
	makert(nd+1);
	int m=getint();
	while(m--){
		makert(nd+1);
		char op=getchar();while(!isalpha(op))op=getchar();
		if(op=='Q'){
			int x=getint();node *v=nd+x;
			access(v);
			printf("%lld\n",v->cha.sum);
		}else
		if(op=='C'){
			int x=getint(),y=getint();
			cut(nd+x);
			makert(nd+y);
			link(nd+y,nd+x);
			makert(nd+1);
		}else{
			int x=getint();node *v=nd+x;
			access(v);
			int y=getint();
			v->val+=y;
			rep(i,2,4)if(v->c[i])
			v->c[i]->makes(flag(y));
		}
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章