记录编号 115020 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008]树的统计Count 最终得分 100
用户昵称 GravatarChenyao2333 是否通过 通过
代码语言 C++ 运行时间 1.575 s
提交时间 2014-08-12 23:05:03 内存使用 3.98 MiB
显示代码纯文本
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<string.h>

using namespace std;

const int INF=1e8;
const int MAXN=30000+10;

vector<int> G[MAXN];

struct seg_tree{
	struct node{
		int num,mx_num,sum;
		int left,right;
		int left_son,right_son;
		node(int left=0,int right=0):
			left(left),right(right){
				num=mx_num=sum=-INF;
				left_son=right_son=0;
			}
	}nodes[MAXN*3];
	int node_cnt;
	void init(){
		node_cnt=0;
	}
	seg_tree(){
		init();
	}
	void update(int no){
		node & now=nodes[no];
		now.mx_num=-INF;
		if(now.left_son!=0 && now.right_son!=0){
			node & left_node=nodes[now.left_son];
			node & right_node=nodes[now.right_son];
			now.mx_num=max(left_node.mx_num,right_node.mx_num);
			now.sum=left_node.sum+right_node.sum;
		}else{
			now.mx_num=now.num;
			now.sum=now.num;
		}
	}
	void build_tree(int no,int left,int right,int info[]){
		node & now=nodes[no];
		now=node(left,right);
		if(left==right){
			now.num=info[left];
		}else{
			int mid=(left+right)/2;
			now.left_son=node_cnt;
			build_tree(node_cnt++,left,mid,info);
			now.right_son=node_cnt;
			build_tree(node_cnt++,mid+1,right,info);
		}
		update(no);
	}
	int get_max_num(int no,int left,int right){
		node & now=nodes[no];
		if(now.left>right || now.right<left) return -INF;
		else if(now.left>=left && now.right<=right){
			return now.mx_num;
		}else{
			int ret=-INF;
			ret=max(ret,get_max_num(now.left_son,left,right));
			ret=max(ret,get_max_num(now.right_son,left,right));
			return ret;
		}
	}
	int get_sum(int no,int left,int right){
		node & now=nodes[no];
		if(now.left>right || now.right<left)return 0;
		else if(now.left>=left && now.right<=right){
			return now.sum;
		}else {
			int ret=0;
			ret+=get_sum(now.left_son,left,right);
			ret+=get_sum(now.right_son,left,right);
			return ret;
		}
	}
	void change_num(int no,int mu,int num){
		node & now=nodes[no];
		if(now.left==now.right){
			now.num=num;
		}else{
			int mid=(now.left+now.right)/2;
			if(mu<=mid)change_num(now.left_son,mu,num);
			else change_num(now.right_son,mu,num);
		}
		update(no);
	}
};

struct light_heavy_dec{
	int fa[MAXN],son[MAXN],deep[MAXN],size[MAXN],top[MAXN],map_to_tree[MAXN];
	int dfs_clock;
	seg_tree st;
	void init(){
		st.init();
		dfs_clock=1;
		memset(fa,0,sizeof(fa));
		memset(son,0,sizeof(son));
		memset(deep,0,sizeof(deep));
		memset(size,0,sizeof(size));
		memset(top,0,sizeof(top));
		memset(map_to_tree,0,sizeof(map_to_tree));
	}
	light_heavy_dec(){
		init();
	}
	void dfs1(int u,int fa_,int deep_){
		fa[u]=fa_;
		deep[u]=deep_;
		size[u]=1;
		for(int i=0;i<G[u].size();i++){
			int v=G[u][i];
			if(v!=fa_){
				dfs1(v,u,deep_+1);
				size[u]+=size[v];
			}
		}

	}

	void dfs2(int u,int fa_top){
		top[u]=fa_top;
		map_to_tree[u]=dfs_clock++;

		int mx_size=0;
		int mx_heavy_son=0;
		for(int i=0;i<G[u].size();i++){
			int v=G[u][i];
			if(v==fa[u])continue;
			if(size[v]>mx_size)mx_size=size[v],mx_heavy_son=v;
		}

		if(mx_size!=0){
			dfs2(mx_heavy_son,fa_top);
			son[u]=mx_heavy_son;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(v==fa[u] || v==mx_heavy_son)continue;
				dfs2(v,v);
			}
		}
	}

	int get_sum(int u,int v){
		int f1=top[u];int f2=top[v];
		int ret=0;
		while(f1!=f2){
			if(deep[f1]<deep[f2])swap(f1,f2),swap(u,v);
			ret+=st.get_sum(0,map_to_tree[f1],map_to_tree[u]);
			u=fa[f1];
			f1=top[u];
		}
		if(map_to_tree[u]>map_to_tree[v])swap(u,v);
		ret+=st.get_sum(0,map_to_tree[u],map_to_tree[v]);
		return ret;
	}
	int get_max(int u,int v){
		int f1=top[u];int f2=top[v];
		int ret=-INF;
		while(f1!=f2){
			if(deep[f1]<deep[f2])swap(f1,f2),swap(u,v);
			ret=max(ret,st.get_max_num(0,map_to_tree[f1],map_to_tree[u]));
			u=fa[f1];
			f1=top[u];
		}
		if(map_to_tree[u]>map_to_tree[v])swap(u,v);
		ret=max(ret,st.get_max_num(0,map_to_tree[u],map_to_tree[v]));
		return ret;
	}
	void change_num(int u,int num){
		st.change_num(0,map_to_tree[u],num);
	}
	void build(int info[]){
		st.build_tree(st.node_cnt++,1,size[1],info);
	}
}solver;

int N,Q;
int date[MAXN];
int date_[MAXN];

void add_edge(int u,int v){
	G[u].push_back(v);
	G[v].push_back(u);
}

void read(){
	scanf("%d",&N);
	for(int i=0;i<N-1;i++){
		int u,v;scanf("%d %d",&u,&v);
		add_edge(u,v);
	}
	for(int i=1;i<=N;i++){
		scanf("%d",&date[i]);
	}
	solver.dfs1(1,0,1);
	solver.dfs2(1,1);
	for(int i=1;i<=N;i++){
		date_[solver.map_to_tree[i]]=date[i];
	}
	solver.build(date_);
}

void work(){
	int Q;scanf("%d",&Q);
	for(int i=1;i<=Q;i++){
		char op[10];
		int a,b;
		scanf("%s",&op);
		scanf("%d %d",&a,&b);
		if(op[0]=='C'){
			solver.change_num(a,b);
		}else if(op[1]=='S'){
			int sum=solver.get_sum(a,b);
			printf("%d\n",sum);
		}else{
			int mx=solver.get_max(a,b);
			printf("%d\n",mx);
		}
	}
}

int main(){
	freopen("bzoj_1036.in","r",stdin);
	freopen("bzoj_1036.out","w",stdout);
	read();
	work();
	return 0;
}