zoukankan      html  css  js  c++  java
  • P3178 [HAOI2015]树上操作

    树剖 LCA DFS序板子题

    #include<bits/stdc++.h>
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,a,n) for(int i=n;i>=a;--i)
    #define pb push_back
    #define fi first
    #define se second
    #define io std::ios::sync_with_stdio(false)
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    inline int lson(int x){return x*2;}
    inline int rson(int x){return x*2+1;}
    const int  maxn=1e5+50;
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll qpow(ll a,ll n)
    {
        ll r=1%P;
        for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;
        return r;
    }
    ll pos[maxn],out[maxn],top[maxn],cnt;
    ll a[maxn],b[maxn];
    ll sum[maxn*4],tag[maxn*4];
    ll _next[maxn*2],head[maxn],tot,to[maxn*2];
    ll sz[maxn];
    ll f[maxn];
    ll n,m;
    void add(ll x,ll y)
    {
        _next[++tot]=head[x],head[x]=tot,to[tot]=y;
        _next[++tot]=head[y],head[y]=tot,to[tot]=x;
    }
    void dfs(ll u,ll fa)
    {
        sz[u]=1;
        f[u]=fa;
        for(ll i=head[u];i;i=_next[i])
        {
            ll v=to[i];
            if(v==fa)continue;
            dfs(v,u);
            sz[u]+=sz[v];
        }
    }
    void dfs2(ll u,ll fa,ll t)
    {
         ll _max=-1;
         ll son=-1;
         pos[u]=out[u]=++cnt;
         b[cnt]=a[u];
         top[u]=t;
        for(ll i=head[u];i;i=_next[i])
        {
            ll v=to[i];
            if(v==fa)
                continue;
            if(sz[v]>_max)
                _max=sz[v],son=v;
        }
        if(son!=-1)
        dfs2(son,u,t);
        for(ll i=head[u];i;i=_next[i])
        {
            ll v=to[i];
            if(v==fa||v==son) continue;
            dfs2(v,u,v);
        }
        out[u]=cnt;
    }
    void build(ll id, ll l,ll r)
    {
        if(l==r)
        {
             sum[id]=b[l];
             return ;
        }
        ll mid=(l+r)/2;
        build(id*2,l,mid);
        build(id*2+1,mid+1,r);
        sum[id]=sum[id*2]+sum[id*2+1];
    }
    void pushdown(ll l,ll r,ll id)
    {
        if(l==r)return ;
        ll t=tag[id];
        tag[id]=0;
        tag[id*2]+=t;
        tag[id*2+1]+=t;
        ll mid=(l+r)/2;
        sum[id*2]+=(mid-l+1)*t;
        sum[id*2+1]+=(r-mid)*t;
    }
    void update(ll id,ll l,ll r,ll ql,ll qr,ll k)
    {
        if(tag[id]!=0)pushdown(l,r,id);
        if(l>=ql&&r<=qr)
        {
            tag[id]+=k;
            sum[id]+=(r-l+1)*k;
            return ;
        }
        ll mid=(l+r)/2;
        if(mid>=ql)update(id*2,l,mid,ql,qr,k);
        if(mid<qr)update(id*2+1,mid+1,r,ql,qr,k);
        sum[id]=sum[id*2]+sum[id*2+1];
    }
    ll query(ll id,ll l,ll r,ll ql,ll qr)
    {
          if(tag[id]!=0)pushdown(l,r,id);
          if(l>=ql&&r<=qr)return sum[id];
          ll ans=0;
          ll mid=(l+r)/2;
          if(mid>=ql)ans+=query(id*2,l,mid,ql,qr);
          if(mid<qr)ans+=query(id*2+1,mid+1,r,ql,qr);
          return ans;
    }
    ll answer(ll x)
    {
        ll ans=0;
        while(x!=0)
        {
           ans+=query(1,1,n,pos[top[x]],pos[x]);
           x=top[x];
           x=f[x];
        }
        return ans;
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=n;i++) scanf("%lld",a+i);
        for(ll i=1;i<n;i++)
        {   
            ll y,x;
            scanf("%lld%lld",&x,&y);
            add(x,y);
        }
        dfs(1,0);
        dfs2(1,0,1);
        build(1,1,n);
        while(m--)
        {
            ll op,x,p;
            scanf("%lld",&op);
            if(op==1)
            {
                scanf("%lld%lld",&x,&p);
                update(1,1,n,pos[x],pos[x],p);
            }
            if(op==2)
            {
             scanf("%lld%lld",&x,&p);
             update(1,1,n,pos[x],out[x],p);
            }
            if(op==3)
            {
                scanf("%lld",&x);
                printf("%lld
    ",answer(x));
            }
        }
    }
  • 相关阅读:
    [开发笔记usbTOcan]PyUSB访问设备
    spring之web.xml
    SpringMVC中Controller如何将数据返回
    总结
    流的append
    对象,构造方法、类
    多态
    类的多态性
    环境变量
    构造方法和成员方法的区别
  • 原文地址:https://www.cnblogs.com/acmLLF/p/13650890.html
Copyright © 2011-2022 走看看