• BZOJ 4034 洛谷3178 树上操作题解


    一个很裸的树链剖分模板。注意一下数据范围,有的地方要开longlong,这就是唯一的陷阱了。

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<algorithm>
    using std::max;
    using std::min;
    const int mn = 100005;
    typedef long long LL;
    struct edge{int to,next;};
    edge e[mn*2];
    int edge_max,head[mn];
    void add(int x,int y)
    {
        e[++edge_max].to=y;
        e[edge_max].next=head[x];
        head[x]=edge_max;
    }
    int n,m;
    int val[mn];
    int fa[mn],siz[mn];
    void dfs1(int x)
    {
        siz[x]=1;
        for(int i=head[x];i;i=e[i].next)
        {
           int v=e[i].to;
           if(v==fa[x])
             continue;
           fa[v]=x;
           dfs1(v);
           siz[x]+=siz[v];
        }
    }
    int tot,id[mn],bl[mn],mx[mn];
    void dfs2(int x,int chain)
    {
        int k=0;
        ++tot;
        id[x]=mx[x]=tot;
        bl[x]=chain;
        for(int i=head[x];i;i=e[i].next)
        {
            if(e[i].to!=fa[x] && siz[e[i].to]>siz[k])
                k=e[i].to;
        }
        if(k==0)
            return ;
        dfs2(k,chain);
        mx[x]=max(mx[x],mx[k]);
        for(int i=head[x];i;i=e[i].next)
        {
            if(fa[x]!=e[i].to && e[i].to!=k)
            {
                dfs2(e[i].to,e[i].to);
                mx[x]=max(mx[x],mx[e[i].to]);
            }
        }
    }
    struct node{int l,r;LL sum,tag;};
    node tr[mn*4];
    inline void pushdown(int cur)
    {
        if(tr[cur].tag && tr[cur].l!=tr[cur].r)
        {
            tr[cur<<1].tag+=tr[cur].tag;
            tr[cur<<1|1].tag+=tr[cur].tag;
            tr[cur<<1].sum+=(tr[cur<<1].r-tr[cur<<1].l+1)*tr[cur].tag;
            tr[cur<<1|1].sum+=(tr[cur<<1|1].r-tr[cur<<1|1].l+1)*tr[cur].tag;
            tr[cur].tag=0;
        }
    }
    void build(int l,int r,int cur)
    {
        tr[cur].l=l,tr[cur].r=r;
        if(l==r)
        {
            return ;
        }
        int mid=l+r>>1;
        build(l,mid,cur<<1);
        build(mid+1,r,cur<<1|1);
    }
    void update(int cur,int l,int r,LL x)//此处要开longlong防止下面爆掉
    {
        if(tr[cur].r<l || tr[cur].l>r)
            return ;
        pushdown(cur);
        if(tr[cur].l>=l && tr[cur].r<=r)
        {
            tr[cur].sum+=(tr[cur].r-tr[cur].l+1)*x;//就是这里容易爆掉
            tr[cur].tag+=x;
            return ;
        }
        update(cur<<1,l,r,x);
        update(cur<<1|1,l,r,x);
        tr[cur].sum=tr[cur<<1].sum+tr[cur<<1|1].sum;
    }
    LL qsum(int cur,int l,int r)
    {
        if(tr[cur].r<l || tr[cur].l>r)
            return 0;
        pushdown(cur);
        if(tr[cur].l>=l && tr[cur].r<=r)
          return tr[cur].sum;
        LL tmp=0;
        tmp+=qsum(cur<<1,l,r);
        tmp+=qsum(cur<<1|1,l,r);
        tr[cur].sum=tr[cur<<1].sum+tr[cur<<1|1].sum;
        return tmp;
    }
    void querry(int x)
    {
        LL ans=0;
        while(bl[x]!=1)
        {
            ans+=qsum(1,id[bl[x]],id[x]);
            x=fa[bl[x]];
        }
        ans+=qsum(1,1,id[x]);
        printf("%lld
    ",ans);
    }
    int main()
    {
        int opt,x,y;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&val[i]);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs1(1);
        dfs2(1,1);
        build(1,n,1);
        for(int i=1;i<=n;i++)
            update(1,id[i],id[i],val[i]);
        for(int i=1;i<=m;i++)
        {
           scanf("%d",&opt);
           if(opt==1)
           {
               scanf("%d%d",&x,&y);
               update(1,id[x],id[x],y*1ll);
           }
           else if(opt==2)
           {
               scanf("%d%d",&x,&y);
               update(1,id[x],mx[x],y*1ll);
           }
           else {
            scanf("%d",&x);
            querry(x);
           }
        }
        return 0;
    }
    

      

  • 相关阅读:
    学习笔记-第八周-PLC梯形图编程
    学习笔记-第六周-学习笔记
    学习笔记-第五周-学习笔记
    学习笔记-第四周-心得体会
    学习笔记-第四周-交流电机选优
    学习笔记-第3周-阅读材料&课本预习
    学习笔记-第3周-电机参数优选
    开发日志
    实时软件控制第四周作业
    实时软件控制第三周作业
  • 原文地址:https://www.cnblogs.com/logeadd/p/8723651.html
Copyright © 2020-2023  润新知