zoukankan      html  css  js  c++  java
  • haoi2015 树上操作

    #include<cstdio>
    #include<algorithm>
    using namespace std;

    typedef  long long ll ;

    struct my{
       ll next;
       ll v;
    };

    const int maxn=500000+20;
    my tu[maxn];
    ll d[maxn],size[maxn],fa[maxn],myson[maxn];
    ll sum[maxn*8],lazy[maxn*8];
    ll dfsn[maxn],last[maxn],top[maxn],pre[maxn];
    ll dfn;
    ll n,m;
    ll adj[maxn];
    ll w[maxn];
    ll tot;

    void myinsert(ll u,ll v){
         tu[++tot].v=v;
         tu[tot].next=adj[u];
         adj[u]=tot;
    }

    void dfs1(int u,int f){
         size[u]=1;
         for (int i=adj[u];i;i=tu[i].next){
            int v=tu[i].v;
            if(v==f) continue;
            d[v]=d[u]+1;fa[v]=u;
            dfs1(v,u);
            size[u]+=size[v];
            if(size[v]>size[myson[u]]) myson[u]=v;
         }
    }

    void dfs2(int u,int frist){
         dfsn[u]=++dfn;
         pre[dfn]=u;
         top[u]=frist;
         if(myson[u]) dfs2(myson[u],frist);
         for (int i=adj[u];i;i=tu[i].next){
             int v=tu[i].v;
             if(v==fa[u]||v==myson[u]) continue;
             dfs2(v,v);
         }
         last[u]=dfn;
    }

    void pushup(ll x){
        sum[x]=sum[x<<1]+sum[x<<1|1];
    }

    void build(ll l,ll r,ll rt){
         if(l==r){
            sum[rt]=w[pre[l]];
            return ;
         }
         int mid=(l+r)>>1;
         build(l,mid,rt<<1);
         build(mid+1,r,rt<<1|1);
         pushup(rt);
    }

    void pushdown(ll x,ll ln,ll rn){
         if(lazy[x]){
            sum[x<<1]+=lazy[x]*ln;
            sum[x<<1|1]+=lazy[x]*rn;
            lazy[x<<1]+=lazy[x];
            lazy[x<<1|1]+=lazy[x];
            lazy[x]=0;
         }
    }

    void change(ll l,ll r,ll rt,ll L,ll R,ll c){
         if(L<=l&&r<=R){
            sum[rt]+=c*(r-l+1);
            lazy[rt]+=c;
            return ;
         }
         ll mid=(l+r)>>1;
         pushdown(rt,mid-l+1,r-mid);
         if(L<=mid) change(l,mid,rt<<1,L,R,c);
         if(R>mid) change(mid+1,r,rt<<1|1,L,R,c);
         pushup(rt);
    }

    ll query(ll l,ll r,ll rt,ll L,ll R){
        if(L<=l&&r<=R){
            return sum[rt];
        }
        ll mid=(l+r)>>1;
        ll ans=0;
        pushdown(rt,mid-l+1,r-mid);
        if(L<=mid) ans+=query(l,mid,rt<<1,L,R);
        if(R>mid) ans+=query(mid+1,r,rt<<1|1,L,R);
        return ans;
    }

    ll getans(ll u){
        long long tu=top[u],ans=0;
        while (tu!=1){
            ans+=query(1,n,1,dfsn[tu],dfsn[u]);
            u=fa[tu];
            tu=top[u];
        }
        ans+=query(1,n,1,dfsn[1],dfsn[u]);
        return ans;
    }

    int main(){
        scanf("%lld%lld",&n,&m);
        for (ll i=1;i<=n;i++){
            scanf("%lld",&w[i]);
        }
        ll u,v;
        for (ll i=1;i<n;i++){
            scanf("%lld%lld",&u,&v);
            myinsert(u,v);
            myinsert(v,u);
        }
      d[1]=1;
      fa[1]=-1;
      dfs1(1,-1);
      dfs2(1,1);
      n;
      build(1,n,1);
       ll biao;
       ll x;
       ll a;
       while(m--){
         scanf("%lld",&biao);
         if(biao==1) {
              scanf("%lld%lld",&x,&a);
              change(1,n,1,dfsn[x],dfsn[x],a);
         }
         if(biao==2){
            scanf("%lld%lld",&x,&a);
            change(1,n,1,dfsn[x],last[x],a);
         }
         if(biao==3) {
            scanf("%lld",&x);
            printf("%lld ",getans(x));
         }
       }
    return 0;
    }

  • 相关阅读:
    linux-kernel邮件列表订阅出错,提示命令不能识别---解决方案
    MD5(单向散列算法)原理分析
    win32汇编跳转指令用法
    (转载)c/c++优先级列表
    linux man手册各个章节的意义
    如何解决dpkg: error processing install-info
    python魔法函数(常见)
    redis 哈希封装
    数据库去重
    抖音破解字体加密
  • 原文地址:https://www.cnblogs.com/lmjer/p/8505602.html
Copyright © 2011-2022 走看看