| 记录编号 |
144840 |
评测结果 |
AAAAAAAAAA |
| 题目名称 |
1688.[ZJOI 2008]树的统计Count |
最终得分 |
100 |
| 用户昵称 |
JSX |
是否通过 |
通过 |
| 代码语言 |
C++ |
运行时间 |
0.653 s |
| 提交时间 |
2014-12-30 11:27:12 |
内存使用 |
2.16 MiB |
显示代码纯文本
#include<cstdio>
const int maxn=30001;
const int size=65537;
int N,M,Q,cnt,len,g[maxn];
int MAX[size],SUM[size];
int fa[maxn],siz[maxn],top[maxn],son[maxn],dep[maxn],w[maxn],v[maxn];
struct Edge{
int to,next;
}e[maxn<<1];
int max(int x,int y){
if(x>y) return x;
return y;
}
int swap(int &x,int &y){
x=x^y,y=x^y,x=x^y;
}
void Getz(int &x){
int ch;
while(ch=getchar(),ch<48||ch>57);x=ch-48;
while(ch=getchar(),ch>47&&ch<58) x=x*10+ch-48;
}
void Getf(int &x){
int ch,flag=0;
while(ch=getchar(),ch<48||ch>57) if(ch==45) break;
if(ch==45) x=0,flag=1;
else x=ch-48;
while(ch=getchar(),ch>47&&ch<58) x=x*10+ch-48;
if(flag) x=-x;
}
void Add_Edge(int x,int y){
e[++len].to=y,e[len].next=g[x],g[x]=len;
}
void DFS1(int x){
siz[x]=1;
for(int i=g[x];i;i=e[i].next){
int t=e[i].to;
if(t==fa[x]) continue;
fa[t]=x,dep[t]=dep[x]+1;
DFS1(t),siz[x]+=siz[t];
if(siz[t]>siz[son[x]]) son[x]=t;
}
}
void DFS2(int x,int tp){
w[x]=++cnt,top[x]=tp,MAX[cnt+M]=SUM[cnt+M]=v[x];
if(son[x]) DFS2(son[x],tp);
for(int i=g[x];i;i=e[i].next){
int t=e[i].to;
if(t==fa[x]||t==son[x]) continue;
DFS2(t,t);
}
}
void Change(int i,int x){
for(i+=M,SUM[i]=MAX[i]=x,i>>=1;i;i>>=1){
MAX[i]=max(MAX[i<<1],MAX[(i<<1)^1]);
SUM[i]=SUM[i<<1]+SUM[(i<<1)^1];
}
}
int Sum(int s,int t){
int sum=0;
for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){
if(~s&1) sum+=SUM[s^1];
if( t&1) sum+=SUM[t^1];
}
return sum;
}
int Max(int s,int t){
int res=-maxn;
for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){
if(~s&1) res=max(res,MAX[s^1]);
if( t&1) res=max(res,MAX[t^1]);
}
return res;
}
void Qsum(int x,int y){
int sum=0;
for(int fx=top[x],fy=top[y];fx!=fy;fx=top[x=fa[fx]]){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
sum+=Sum(w[fx],w[x]);
}
if(dep[x]>dep[y]) swap(x,y);
printf("%d\n",sum+Sum(w[x],w[y]));
}
void Qmax(int x,int y){
int res=-maxn;
for(int fx=top[x],fy=top[y];fx!=fy;fx=top[x=fa[fx]]){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
res=max(res,Max(w[fx],w[x]));
}
if(dep[x]>dep[y]) swap(x,y);
printf("%d\n",max(res,Max(w[x],w[y])));
}
int main(){
freopen("bzoj_1036.in","r",stdin);
freopen("bzoj_1036.out","w",stdout);
Getz(N);
for(M=1;M<N+2;M<<=1);
for(int x,y,i=1;i<N;i++){
Getz(x),Getz(y);
Add_Edge(x,y),Add_Edge(y,x);
}
for(int i=1;i<=N;i++) Getf(v[i]);
DFS1(1),DFS2(1,1);
for(int i=M;i>=1;i--){
MAX[i]=max(MAX[i<<1],MAX[(i<<1)^1]);
SUM[i]=SUM[i<<1]+SUM[(i<<1)^1];
}
Getz(Q);
while(Q--){
int ch,x,y;
while((ch=getchar())<65);
if(ch=='C') Getz(x),Getf(y),Change(w[x],y);
else if(getchar()=='S') Getz(x),Getz(y),Qsum(x,y);
else Getz(x),Getz(y),Qmax(x,y);
}
}