• bzoj4034 [HAOI2015]树上操作——树链剖分


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4034

    树剖裸题;

    一定要注意 long long !!!

    update 的时候别忘了 pushdown ...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int const maxn=1e5+5;
    int n,m,tim,dfn[maxn],id[maxn],top[maxn],son[maxn],siz[maxn],fa[maxn];
    int hd[maxn],ct,a[maxn],end[maxn];
    ll sum[maxn<<2],lzy[maxn<<2];//ll
    struct N{
        int to,nxt;
        N(int t=0,int n=0):to(t),nxt(n) {}
    }ed[maxn<<1];
    void add(int x,int y){ed[++ct]=N(y,hd[x]); hd[x]=ct;}
    void dfs(int x)
    {
        siz[x]=1;
        for(int i=hd[x],u;i;i=ed[i].nxt)
        {
            if((u=ed[i].to)==fa[x])continue;
            fa[u]=x; dfs(u); siz[x]+=siz[u];
            if(siz[u]>siz[son[x]])son[x]=u;
        }
    }
    void dfs2(int x)
    {
        id[dfn[x]=++tim]=x;
        if(son[x])top[son[x]]=top[x],dfs2(son[x]);
        for(int i=hd[x],u;i;i=ed[i].nxt)
        {
            if((u=ed[i].to)==fa[x]||u==son[x])continue;
            top[u]=u; dfs2(u);
        }
        end[x]=tim;
    }
    void pushup(int x){sum[x]=sum[x<<1]+sum[x<<1|1];}
    void pushdown(int x,int l,int r)
    {
        if(lzy[x])
        {
            int ls=(x<<1),rs=(x<<1|1),mid=((l+r)>>1);
            sum[ls]+=lzy[x]*(mid-l+1); lzy[ls]+=lzy[x];
            sum[rs]+=lzy[x]*(r-mid); lzy[rs]+=lzy[x];
            lzy[x]=0;
        }
    }
    void build(int x,int l,int r)
    {
        if(l==r){sum[x]=a[id[l]]; return;}
        int mid=((l+r)>>1);
        build(x<<1,l,mid); build(x<<1|1,mid+1,r);
        pushup(x);
    }
    ll query(int x,int l,int r,int L,int R)
    {
        if(l>=L&&r<=R)return sum[x];
        pushdown(x,l,r);
        int mid=((l+r)>>1); ll ret=0;
        if(mid>=L)ret+=query(x<<1,l,mid,L,R);
        if(mid<R)ret+=query(x<<1|1,mid+1,r,L,R);
        return ret;
    }
    void update(int x,int l,int r,int L,int R,ll v)//ll
    {
        if(l>=L&&r<=R){sum[x]+=v*(r-l+1); lzy[x]+=v; return;}
        pushdown(x,l,r);//!!!
        int mid=((l+r)>>1);
        if(mid>=L)update(x<<1,l,mid,L,R,v);
        if(mid<R)update(x<<1|1,mid+1,r,L,R,v);
        pushup(x);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1,x,y;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y); add(y,x);
        }
        dfs(1); top[1]=1; dfs2(1); build(1,1,n);
        for(int i=1,p,x;i<=m;i++)
        {
            ll v;//
            scanf("%d%d",&p,&x);
            if(p==1){scanf("%lld",&v); update(1,1,n,dfn[x],dfn[x],v);}
            if(p==2){scanf("%lld",&v); update(1,1,n,dfn[x],end[x],v);}
            if(p==3)
            {
                ll ans=0;
                while(x)//
                {
                    ans+=query(1,1,n,dfn[top[x]],dfn[x]);//顺序 
                    x=fa[top[x]];
                }
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    记swoole数据库连接池消失问题的解决方式
    表格逻辑的几个想法
    Java代码实现热部署
    一个接口代理demo
    thinkphp5 关于跨域的一些坑
    CoSky-Mirror 就像一个镜子放在 Nacos、CoSky 中间,构建一个统一的服务发现平台
    CoSky 高性能 服务注册/发现 & 配置中心
    Govern Service 基于 Redis 的服务治理平台
    Govern EventBus
    mysql中查看视图代码
  • 原文地址:https://www.cnblogs.com/Zinn/p/9296304.html
Copyright © 2020-2023  润新知