zoukankan      html  css  js  c++  java
  • [BZOJ 4034] 树上操作

    Link:

    BZOJ 4034 传送门

    Solution:

    树剖模板题……

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    #define mid ((l+r)>>1)
    #define lc k<<1,l,mid
    #define rc k<<1|1,mid+1,r
    const int MAXN=1e5+10;
    struct edge{int to,nxt;}e[MAXN<<2];
    ll seg[MAXN<<2],tag[MAXN<<2];
    int n,m,x,y,head[MAXN],dep[MAXN],dat[MAXN],sz[MAXN],top[MAXN],pos[MAXN],f[MAXN],cnt,tot;
    
    void add_edge(int from,int to)
    {e[++tot].nxt=head[from];e[tot].to=to;head[from]=tot;}
    
    void dfs1(int x)
    {
        sz[x]=1;
        for(int i=head[x];i;i=e[i].nxt)
        {
            if(e[i].to==f[x]) continue;
            f[e[i].to]=x;dep[e[i].to]=dep[x]+1;
            dfs1(e[i].to);sz[x]+=sz[e[i].to]; 
        }
    }
    
    void dfs2(int x,int up)
    {
        int bs=0;top[x]=up;pos[x]=++cnt;
        for(int i=head[x];i;i=e[i].nxt)
            if(e[i].to!=f[x]&&sz[e[i].to]>sz[bs]) bs=e[i].to;
        if(!bs) return;
        dfs2(bs,up);
        for(int i=head[x];i;i=e[i].nxt)
            if(e[i].to!=f[x]&&e[i].to!=bs) dfs2(e[i].to,e[i].to);
    }
    
    void pushdown(int k,int l,int r)
    {
        if(!tag[k]) return;
        tag[k<<1]+=tag[k];tag[k<<1|1]+=tag[k];
        seg[k<<1]+=tag[k]*(mid-l+1);
        seg[k<<1|1]+=tag[k]*(r-mid);
        tag[k]=0;
    }
    
    void Update(int a,int b,int x,int k,int l,int r)
    {
        if(a<=l&&r<=b)
        {seg[k]+=1ll*x*(r-l+1);tag[k]+=x;return;}
        
        pushdown(k,l,r);
        if(a<=mid) Update(a,b,x,lc);
        if(b>mid) Update(a,b,x,rc);
        seg[k]=seg[k<<1]+seg[k<<1|1];
    }
    
    ll Query(int a,int b,int k,int l,int r)
    {
        if(a<=l&&r<=b) return seg[k];
        ll ret=0;pushdown(k,l,r);
        if(a<=mid) ret+=Query(a,b,lc);
        if(b>mid) ret+=Query(a,b,rc);
        return ret;
    }
    
    ll solve_query(int a,int b)
    {
        ll ret=0;
        while(top[a]!=top[b])
        {
            if(dep[top[a]]<dep[top[b]]) swap(a,b);
            ret+=Query(pos[top[a]],pos[a],1,1,n);
            a=f[top[a]];
        }
        if(pos[a]>pos[b]) swap(a,b);
        ret+=Query(pos[a],pos[b],1,1,n);
        return ret;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&dat[i]);
        for(int i=1;i<n;i++)
            scanf("%d%d",&x,&y),add_edge(x,y),add_edge(y,x);
        dfs1(1);dfs2(1,1);
        for(int i=1;i<=n;i++) Update(pos[i],pos[i],dat[i],1,1,n);
        
        while(m--)
        {
            int op,x,a;scanf("%d%d",&op,&x);
            if(op!=3) scanf("%d",&a);
            if(op==1) Update(pos[x],pos[x],a,1,1,n);
            else if(op==2) Update(pos[x],pos[x]+sz[x]-1,a,1,1,n); 
            else printf("%lld
    ",solve_query(1,x));
        }
        return 0;
    }
  • 相关阅读:
    PHP
    优秀网址
    客户关系管理系统CRM
    面试题
    练习并熟练掌握交互式 SQL 语言
    嵌入式的SQL程序设计
    数据库总结
    JDBC
    玩转Android之Drawable的使用
    Android开发之Activity转场动画
  • 原文地址:https://www.cnblogs.com/newera/p/9297638.html
Copyright © 2011-2022 走看看