zoukankan      html  css  js  c++  java
  • 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
    ",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;
    }
  • 相关阅读:
    Sharp Develop发布了1.0.3版本
    【历代Windows操作系统大观】(转)
    Matlab与vc混合编程中的问题,使用idl文件
    明天回湖北!今天要开始收拾烂摊子了
    MongoDB深究之ObjectId
    MVC设计模式
    ASP.NET验证控件详解
    C# 中的 LINQ 入门学习摘记
    15款在线科学计算器
    从底层了解ASP.NET架构
  • 原文地址:https://www.cnblogs.com/harden/p/6407833.html
Copyright © 2011-2022 走看看