http://acm.split.hdu.edu.cn/showproblem.php?pid=3966
模板题贴模板
手动扩栈
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstring>
#include<cstdio>
const int maxn=50010;
using namespace std;
struct node{
int v,next;
}edges[maxn<<1];int tot,head[maxn],n;
void addedge(int u,int v){
edges[tot].v=v;
edges[tot].next=head[u];
head[u]=tot++;
}
int deep[maxn],top[maxn],fa[maxn],size[maxn],p[maxn],fp[maxn],son[maxn];
int pos;
void Init(){
tot=0;
pos=1;
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
}
void dfs1(int u,int pre,int d){
size[u]=1;
fa[u]=pre;
deep[u]=d;
for(int i=head[u];i!=-1;i=edges[i].next){
int v=edges[i].v;
if(v!=pre){
dfs1(v,u,d+1);
size[u]+=size[v];
if(son[u]==-1||size[son[u]]<size[v])
son[u]=v;
}
}
}
void getpos(int u,int sp){
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1) return ;
getpos(son[u],sp);
for(int i=head[u];i!=-1;i=edges[i].next){
int v=edges[i].v;
if(v!=son[u]&&v!=fa[u])
getpos(v,v);
}
}
int c[maxn];
void add(int x,int v){
for(int i=x;i<=n;i+=i&-i){
c[i]+=v;
}
}
int query(int x){
int sum=0;
for(int i=x;i>0;i-=i&-i){
sum+=c[i];
}
return sum;
}
void change(int u,int v,int val){
int f1=top[u],f2=top[v];
while(f1!=f2){
if(deep[f1]<deep[f2]){
swap(f1,f2);
swap(u,v);
}
add(p[f1],val);
add(p[u]+1,-val);
u=fa[f1];f1=top[u];
}
if(deep[u]>deep[v]) swap(u,v);
add(p[u],val);
add(p[v]+1,-val);
}
int a[maxn];
int main()
{
int M,P;
while(scanf("%d%d%d",&n,&M,&P)!=EOF){
int u,v;
int C1,C2,K;
char op[10];
Init();
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
while(M--){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs1(1,0,0);
getpos(1,1);
memset(c,0,sizeof(c));
for(int i=1;i<=n;++i){
add(p[i],a[i]);
add(p[i]+1,-a[i]);
}
while(P--){
scanf("%s",op);
if(op[0]=='Q'){
scanf("%d",&u);
printf("%d\n",query(p[u]));
}
else{
scanf("%d%d%d",&C1,&C2,&K);
if(op[0]=='D') K=-K;
change(C1,C2,K);
}
}
}
return 0;
}