记录编号 458344 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008]树的统计Count 最终得分 100
用户昵称 GravatarFisher. 是否通过 通过
代码语言 C++ 运行时间 1.218 s
提交时间 2017-10-11 07:41:09 内存使用 2.49 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();}
	return x*f;
}
const int maxn=30010;
int n,m;
vector<int>t[maxn];
int val[maxn],sz[maxn],dep[maxn],fa[maxn],top[maxn],id[maxn],pre[maxn],son[maxn],tot;
inline void dfs1(int u,int f,int d){
	sz[u]=1;fa[u]=f;dep[u]=d;
	for(int i=0;i<(int)t[u].size();i++){
		int v=t[u][i];
		if(v==f)continue;
		dfs1(v,u,d+1);
		sz[u]+=sz[v];
		if(!son[u]||sz[son[u]]<sz[v])son[u]=v;
	}
}
inline void dfs2(int u,int tou){
	top[u]=tou;id[u]=++tot;pre[tot]=u;
	if(!son[u])return ;
	dfs2(son[u],tou);
	for(int i=0;i<(int)t[u].size();i++){
		int v=t[u][i];
		if(v!=fa[u]&&v!=son[u])dfs2(v,v);
	}
}
int sum[maxn<<2],maxx[maxn<<2];
inline void build(int o,int l,int r){
	if(l==r){
		sum[o]=val[pre[l]];
		maxx[o]=val[pre[l]];
		return ;
	}
	int m=(l+r)>>1,ls=o<<1,rs=ls|1;
	build(ls,l,m);
	build(rs,m+1,r);
	sum[o]=sum[ls]+sum[rs];
	maxx[o]=max(maxx[ls],maxx[rs]);
}
inline void change(int o,int l,int r,int nl,int nr,int v){
	if(l>=nl&&r<=nr){
		sum[o]=v;
		maxx[o]=v;
		return ;
	}
	int m=(l+r)>>1,ls=o<<1,rs=ls|1;
	if(m>=nl)change(ls,l,m,nl,nr,v);
	if(m<nr)change(rs,m+1,r,nl,nr,v);
	sum[o]=sum[ls]+sum[rs];
	maxx[o]=max(maxx[ls],maxx[rs]);
}
inline int findsum(int o,int l,int r,int nl,int nr){
	if(l>=nl&&r<=nr)return sum[o];
	int m=(l+r)>>1,ls=o<<1,rs=ls|1;
	int ans=0;
	if(m>=nl)ans+=findsum(ls,l,m,nl,nr);
	if(m<nr)ans+=findsum(rs,m+1,r,nl,nr);
	return ans;
}
char ru[10];
inline int findmax(int o,int l,int r,int nl,int nr){
	if(l>=nl&&r<=nr)return maxx[o];
	int m=(l+r)>>1,ls=o<<1,rs=ls|1;
	int ans=-0x7fffffff;
	if(m>=nl)ans=max(ans,findmax(ls,l,m,nl,nr));
	if(m<nr)ans=max(ans,findmax(rs,m+1,r,nl,nr));
	return ans;
}
inline void gsum(int x,int y){
	int u=top[x],v=top[y];
	int ans=0;
	while(u!=v){
		if(dep[u]<dep[v])swap(u,v),swap(x,y);
		ans+=findsum(1,1,n,id[u],id[x]);
		x=fa[u],u=top[x];
	}
	if(dep[x]>dep[y])swap(x,y);
	ans+=findsum(1,1,n,id[x],id[y]);
	printf("%d\n",ans);
}
inline void gmax(int x,int y){
	int u=top[x],v=top[y];
	int ans=-0x7fffffff;
	while(u!=v){
		if(dep[u]<dep[v])swap(u,v),swap(x,y);
		ans=max(ans,findmax(1,1,n,id[u],id[x]));
		x=fa[u],u=top[x];
	}
	if(dep[x]>dep[y])swap(x,y);
	ans=max(ans,findmax(1,1,n,id[x],id[y]));
	printf("%d\n",ans);
}
int main(){
	freopen("bzoj_1036.in","r",stdin);
	freopen("bzoj_1036.out","w",stdout);
	n=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		t[u].push_back(v);
		t[v].push_back(u);  
	}
	for(int i=1;i<=n;i++)val[i]=read();
	dfs1(1,0,1);dfs2(1,1);
	build(1,1,n);
	scanf("%d",&m);
	for(int i=1;i<=m;i++){
		scanf("%s",ru);
		int x,y;
		scanf("%d%d",&x,&y);
		if(ru[1]=='S'){
			gsum(x,y);
		}
		if(ru[1]=='M'){
			gmax(x,y);
		}
		if(ru[1]=='H'){
			change(1,1,n,id[x],id[x],y);
		}
	}
	return 0;
}