zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    7.21 高博教育 数组 内存
    【基础扎实】Python操作Excel三模块
    PAT 甲级 1012 The Best Rank
    PAT 甲级 1011  World Cup Betting
    PAT 甲级 1010 Radix
    链式线性表——实验及提升训练
    循环程序设计能力自测
    链表应用能力自测
    PAT 甲级 1009 Product of Polynomials
    1008 Elevator (20分)
  • 原文地址:https://www.cnblogs.com/Zinn/p/9296304.html
Copyright © 2011-2022 走看看