记录编号 143946 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008]树的统计Count 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 2.622 s
提交时间 2014-12-19 08:57:33 内存使用 1.12 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int SIZEN=30010,INF=0x7fffffff/2;
inline int max(int a,int b,int c){return max(max(a,b),c);}
class Node{
public:
	int lc,rc,fa;
	int val,sum,mx;
	bool inv;
	void clear(void){
		lc=rc=fa=0;
		val=sum=0;mx=-INF;
		inv=0;
	}
	Node(void){clear();}
	#define lc(x) Tree[x].lc
	#define rc(x) Tree[x].rc
	#define fa(x) Tree[x].fa
	#define val(x) Tree[x].val
	#define sum(x) Tree[x].sum
	#define mx(x) Tree[x].mx
	#define inv(x) Tree[x].inv
};
Node Tree[SIZEN];
bool Is_Root(int x){return lc(fa(x))!=x&&rc(fa(x))!=x;}
void Push_Down(int x){
	if(!x) return;
	if(inv(x)){
		swap(lc(x),rc(x));
		inv(lc(x))^=1;
		inv(rc(x))^=1;
		inv(x)=false;
	}
}
void Update(int x){
	if(!x) return;
	sum(x)=sum(lc(x))+sum(rc(x))+val(x);
	mx(x)=max(mx(lc(x)),mx(rc(x)),val(x));
}
void Zig(int x){//右旋
	int y=fa(x),z=fa(y);
	if(lc(z)==y) lc(z)=x;
	if(rc(z)==y) rc(z)=x;
	fa(x)=z;
	lc(y)=rc(x);fa(lc(y))=y;
	rc(x)=y;fa(y)=x;
	Update(y);Update(x);
}
void Zag(int x){//左旋
	int y=fa(x),z=fa(y);
	if(lc(z)==y) lc(z)=x;
	if(rc(z)==y) rc(z)=x;
	fa(x)=z;
	rc(y)=lc(x);fa(rc(y))=y;
	lc(x)=y;fa(y)=x;
	Update(y);Update(x);
}
void Splay(int x){
	Push_Down(x);
	while(!Is_Root(x)){
		int y=fa(x),z=fa(y);
		Push_Down(z);Push_Down(y);Push_Down(x);
		if(Is_Root(y)){
			if(lc(y)==x) Zig(x);
			else Zag(x);
			return;
		}
		if(lc(z)==y){
			if(lc(y)==x) Zig(y),Zig(x);
			else Zag(x),Zig(x);
		}
		else{
			if(rc(y)==x) Zag(y),Zag(x);
			else Zig(x),Zag(x);
		}
	}
}
void Access(int x){
	int y=0;
	while(x){
		Splay(x);
		rc(x)=y;
		Update(x);
		y=x;
		x=fa(x);
	}
}
void Make_Root(int x){
	Access(x);
	Splay(x);
	inv(x)^=1;
}
void Link(int x,int y){
	Make_Root(x);
	fa(x)=y;
}
int Query_Max(int x,int y){
	Make_Root(x);
	Access(y);
	Splay(y);
	return mx(y);
}
int Query_Sum(int x,int y){
	Make_Root(x);
	Access(y);
	Splay(y);
	return sum(y);
}
void Change_Node(int x,int t){
	Access(x);
	Splay(x);
	val(x)=t;
	Update(x);
}
int N,Q;
void Process(void){
	scanf("%d",&Q);
	char cmd[10];
	int a,b;
	for(int i=1;i<=Q;i++){
		scanf("%s",cmd);
		scanf("%d%d",&a,&b);
		if(cmd[0]=='C') Change_Node(a,b);
		else if(cmd[1]=='M') printf("%d\n",Query_Max(a,b));
		else if(cmd[1]=='S') printf("%d\n",Query_Sum(a,b));
	}
}
void Init(void){
	scanf("%d",&N);
	int a,b,w;
	for(int i=1;i<N;i++){
		scanf("%d%d",&a,&b);
		Link(a,b);
	}
	for(int i=1;i<=N;i++){
		scanf("%d",&w);
		Change_Node(i,w);
	}
}
int main(){
	freopen("bzoj_1036.in","r",stdin);
	freopen("bzoj_1036.out","w",stdout);
	Init();
	Process();
	return 0;
}