Aragorn's Story(hdu3966)

题意:给一棵树,并给定各个点权的值,然后有3种操作:

I C1 C2 K: 把C1与C2的路径上的所有点权值加上K

D C1 C2 K:把C1与C2的路径上的所有点权值减去K

Q C:查询节点编号为C的权值

/*
  要手动扩栈。
*/ 
#pragma comment(linker, "/STACK:1024000000,1024000000")  
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 100010
using namespace std;
int a[N],head[N],fa[N],son[N],dep[N],top[N],pos[N],sum[N*4],tag[N*4],n,m,p,sz;
struct node{
    int to,pre;
};node e[N*2];
void add(int i,int x,int y){
    e[i].to=y;
    e[i].pre=head[x];
    head[x]=i;
}
void dfs1(int x){
    son[x]=1;
    for(int i=head[x];i;i=e[i].pre){
        int v=e[i].to;
        if(fa[x]==v) continue;
        fa[v]=x;dep[v]=dep[x]+1;
        dfs1(v);
        son[x]+=son[v];
    }
}
void dfs2(int x,int chain){
    ++sz;pos[x]=sz;top[x]=chain;int k=0,maxn=0;
    for(int i=head[x];i;i=e[i].pre)
        if(fa[x]!=e[i].to&&son[e[i].to]>maxn){
            maxn=son[e[i].to];
            k=e[i].to;
        }
    if(!k)return;
    dfs2(k,chain);
    for(int i=head[x];i;i=e[i].pre)
        if(e[i].to!=fa[x]&&e[i].to!=k)
            dfs2(e[i].to,e[i].to);
}
void pushup(int k){
    sum[k]=sum[k*2]+sum[k*2+1];
}
void pushdown(int k,int l,int r){
    if(!tag[k]) return;
    int mid=l+r>>1;
    tag[k*2]+=tag[k];
    tag[k*2+1]+=tag[k];
    sum[k*2]+=tag[k]*(l-mid+1);
    sum[k*2+1]+=tag[k]*(r-mid);
    tag[k]=0;
}
void change(int l,int r,int k,int x,int y,int v){
    if(l>=x&&r<=y){
        tag[k]+=v;
        sum[k]+=(l-r+1)*v;
        return;
    }
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(x<=mid) change(l,mid,k*2,x,y,v);
    if(y>mid) change(mid+1,r,k*2+1,x,y,v);
    pushup(k);
}
int query(int l,int r,int k,int pos){
    if(l==r)return sum[k];
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(pos<=mid) return query(l,mid,k*2,pos);
    else return query(mid+1,r,k*2+1,pos);
}
void xiugai(int x,int y,int v){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        change(1,n,1,pos[top[x]],pos[x],v);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    change(1,n,1,pos[x],pos[y],v);
}
void work(){
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++){
        int x,y;scanf("%d%d",&x,&y);
        add(i*2-1,x,y);add(i*2,y,x);
    }
    dfs1(1);dfs2(1,1);
    for(int i=1;i<=n;i++)change(1,n,1,pos[i],pos[i],a[i]);
    char opt[10];
    for(int i=1;i<=p;i++){
        int x,y,v;
        scanf("%s",opt);
        if(opt[0]=='I'){
            scanf("%d%d%d",&x,&y,&v);
            xiugai(x,y,v);
        }
        else if(opt[0]=='D'){
            scanf("%d%d%d",&x,&y,&v);
            xiugai(x,y,-v);
        }
        else{
            scanf("%d",&x);
            printf("%d\n",query(1,n,1,pos[x]));
        }
    }
}
int main(){while(scanf("%d%d%d",&n,&m,&p)!=EOF){
        memset(head,0,sizeof(head));
        memset(fa,0,sizeof(fa));
        memset(son,0,sizeof(son));
        memset(dep,0,sizeof(dep));
        memset(top,0,sizeof(top));
        memset(pos,0,sizeof(pos));
        memset(sum,0,sizeof(sum));
        memset(tag,0,sizeof(tag));
        sz=0;
        work();
    }
    return 0;
}

 

posted @ 2017-02-16 22:21  karles~  阅读(185)  评论(0编辑  收藏  举报