http://acm.hdu.edu.cn/showproblem.php?pid=3966
3 2 5 1 2 3 2 1 2 3 I 1 3 5 Q 2 D 1 2 2 Q 1 Q 3
7 4 8Hint1.The number of enemies may be negative. 2.Huge input, be careful.
/** hdu3966 树链剖分(区间更新和单点求值) 题目大意:给定一棵树,对指定的连点之间的点的权进行更新,过程中询问指定点的当前值 解题思路:树链剖分,区间更新维护的题目 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; const int maxn=50005; typedef long long LL; int n,m,q,z; LL a[maxn],sum[maxn*4],col[maxn*4]; int fa[maxn],Hash[maxn],dep[maxn],son[maxn],siz[maxn]; int num[maxn],top[maxn]; int head[maxn],ip; void init() { memset(head,-1,sizeof(head)); memset(col,0,sizeof(col)); memset(sum,0,sizeof(sum)); ip=0; } struct note { int v,next; }edge[maxn*4]; void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++; } void dfs(int u,int pre) { son[u]=0,siz[u]=1,dep[u]=dep[pre]+1,fa[u]=pre; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==pre)continue; dfs(v,u); if(siz[son[u]]<siz[v]) { son[u]=v; } siz[u]+=siz[v]; } ///printf("%d fa,dep,siz,son %d %d %d %d\n",u,fa[u],dep[u],siz[u],son[u]); } void set_que(int u,int tp) { top[u]=tp,num[u]=++z,Hash[z]=u; if(son[u]) { set_que(son[u],tp); } for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa[u]||v==son[u])continue; set_que(v,v); } /// printf("%d top num %d %d\n",u,top[u],num[u]); } void push_up(int root) { sum[root]=sum[root<<1]+sum[root<<1|1]; } void build(int root,int l,int r) { col[root]=0; if(l==r) { sum[root]=a[Hash[l]]; return; } int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); push_up(root); } void push_down(int root,int len) { if(col[root]) { col[root<<1]+=col[root]; col[root<<1|1]+=col[root]; sum[root<<1]+=col[root]*(len-(len>>1)); sum[root<<1|1]+=col[root]*(len>>1); col[root]=0; } } void update(int root,int l,int r,int x,int y,int z) { if(l>y||r<x)return; if(x<=l&&r<=y) { col[root]+=z; sum[root]+=(r-l+1)*z; return; } push_down(root,r-l+1); int mid=(l+r)>>1; update(root<<1,l,mid,x,y,z); update(root<<1|1,mid+1,r,x,y,z); push_up(root); } LL query(int root,int l,int r,int loc) { if(l>loc||r<loc)return 0; if(l==r) { return sum[root]; } push_down(root,r-l+1); int mid=(l+r)>>1; if(loc<=mid) return query(root<<1,l,mid,loc); else return query(root<<1|1,mid+1,r,loc); } int main() { //freopen("data.txt","r",stdin); while(~scanf("%d%d%d",&n,&m,&q)) { init(); for(int i=1;i<=n;i++) { scanf("%I64d",&a[i]); } for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } int root=(n+1)>>1; z=0,dep[0]=0,siz[0]=0; dfs(root,0); set_que(root,root); build(1,1,z); while(q--) { char s[20]; int x,y,zz; scanf("%s",s); if(s[0]=='Q') { scanf("%d",&x); printf("%I64d\n",query(1,1,z,num[x])); } else { scanf("%d%d%d",&x,&y,&zz); if(s[0]=='D')zz=-zz; int f1=top[x],f2=top[y]; while(f1!=f2) { if(dep[f1]<dep[f2]) { swap(f1,f2); swap(x,y); } update(1,1,z,num[f1],num[x],zz); x=fa[f1],f1=top[x]; } if(dep[x]>dep[y]) { swap(x,y); } update(1,1,z,num[x],num[y],zz); } } } return 0; }