记录编号 143512 评测结果 AAAAAAAAAA
题目名称 1688.[ZJOI 2008]树的统计Count 最终得分 100
用户昵称 JSX 是否通过 通过
代码语言 C++ 运行时间 0.682 s
提交时间 2014-12-15 16:11:44 内存使用 3.49 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
const int MAXN = 30010;

int N=0,Q=0,M1=1;
struct node{
	int to,next;
}E[MAXN<<1];
int line[MAXN]={0},tot=0;
inline void Insert(int x,int y){
	tot++; E[tot].to=y; E[tot].next=line[x]; line[x]=tot;
}

inline int Read() {
	int ret,neg;	char ch;
	ret = neg = 0 ; while (!isdigit(ch=getchar())&&ch!='-') ;
	if (ch=='-') neg = 1 , ch=getchar() ;
	while (ret = ret*10+ch-'0' , isdigit(ch=getchar())) ;
	if (neg) ret = -ret ;
	return ret ;
}

int Sum[MAXN<<3]={0},Max[MAXN<<3]={0};
int W[MAXN]={0},Deep[MAXN]={0},Son[MAXN]={0},Fa[MAXN]={0};
int Size[MAXN]={0},ID[MAXN]={0},Top[MAXN]={0};
inline void DFS1(int u){
	Size[u]=1; Son[u]=0;
	for(int i=line[u];i!=0;i=E[i].next){
		int p=E[i].to;
		if(p!=Fa[u]){
			Fa[p]=u; Deep[p]=Deep[u]+1;
			DFS1(p);
			Size[u]+=Size[p];
			if(Size[p]>Size[Son[u]]) Son[u]=p;
		}
	}
}

int cnt=0;
inline void DFS2(int u,int top){
	ID[u]=++cnt; Top[u]=top; Sum[cnt+M1]=Max[cnt+M1]=W[u];
	if(Son[u]) DFS2(Son[u],top);
	for(int i=line[u];i!=0;i=E[i].next){
		int p=E[i].to;
		if(p!=Fa[u] && p!=Son[u]) DFS2(p,p);
	}
}

inline void Updata(int x,int v){
	x+=M1; Sum[x]=v; Max[x]=v;
	for(x>>=1;x;x>>=1){
		Sum[x]=Sum[(x<<1)]+Sum[(x<<1)+1];
		Max[x]=max(Max[(x<<1)],Max[(x<<1)+1]);
	}
} 

inline int Query_Sum(int s,int t){
	int Ans=0;
	for(s=s+M1-1,t=t+M1+1;s^t^1;s>>=1,t>>=1){
		if(!(s&1)) Ans+=Sum[s^1];
		if( (t&1)) Ans+=Sum[t^1];
	}
	return Ans;
}

inline int Query_Max(int s,int t){
	int Ans=-0x3f3f3f3f;
	for(s=s+M1-1,t=t+M1+1;s^t^1;s>>=1,t>>=1){
		if(!(s&1)) Ans=max(Max[s^1],Ans);
		if( (t&1)) Ans=max(Max[t^1],Ans);
	}
	return Ans;
}

inline int Tree_Sum(int x,int y){
	int fx=Top[x],fy=Top[y],Res=0;
	while(fx!=fy){
		if(Deep[fx]<Deep[fy]){ swap(x,y); swap(fx,fy); }
		Res+=Query_Sum(ID[fx],ID[x]);
		x=Fa[fx]; fx=Top[x];
	}
	if(Deep[x]>Deep[y]) swap(x, y);
    return Res+Query_Sum(ID[x],ID[y]);
}

inline int Tree_Max(int x,int y){
	int fx=Top[x],fy=Top[y],Res=-0x3f3f3f3f;
	while(fx!=fy){
		if(Deep[fx]<Deep[fy]){ swap(x,y); swap(fx,fy); }
		Res=max(Query_Max(ID[fx],ID[x]),Res);
		x=Fa[fx]; fx=Top[x];
	}
	if(Deep[x]>Deep[y]) swap(x, y);
    return max(Res,Query_Max(ID[x],ID[y]));
}

int main(){
	freopen("bzoj_1036.in","r",stdin);
	freopen("bzoj_1036.out","w",stdout);
	N=Read();
	int a=0,b=0;
	for(int i=1;i< N;++i){
		a=Read(); b=Read();
		Insert(a,b); Insert(b,a);
	}
	for(int i=1;i<=N;++i) W[i]=Read();
	for(M1=1;M1<N+2;M1<<=1);
	DFS1(1);
	DFS2(1,1);
	//for(int i=1;i<=N;++i) printf("%d  ",Max[i+M1]);printf("\n");
	//for(int i=1;i<=N;++i) printf("%d  ",ID[i]); printf("\n");
	for(int i=M1;i>=1;--i){
		Sum[i]=Sum[(i<<1)]+Sum[(i<<1)+1];
		Max[i]=max(Max[(i<<1)],Max[(i<<1)+1]);
	}
	Q=Read();
	char s[10];
	for(int i=1;i<=Q;++i){
		scanf("%s",s);
		a=Read(); b=Read();
		if(s[0]=='C')   Updata(ID[a],b);
	    if(s[1]=='S'){
	        printf("%d\n",Tree_Sum(a,b));
	    }
	    if(s[1]=='M'){    
	        printf("%d\n",Tree_Max(a,b));
	    }
	}
	return 0;
}