zoukankan      html  css  js  c++  java
  • BZOJ 4034 T2

    树剖。观察这样一个事实:一个子树上的区间一定是连续的。打lazy标记即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxv 200500
    #define maxe 200500
    using namespace std;
    long long n,m,x,y,type,nume=0;
    long long dis[maxv],fath[maxv],son[maxv],w[maxv],mx[maxv],size[maxv],top[maxv],fw[maxv],k[maxv],g[maxv];
    long long cnt=0,tot=0,ls[maxv<<3],rs[maxv<<3],value[maxv<<3],lazy[maxv<<3],root;
    struct edge
    {
        long long v,nxt;
    }e[maxe];
    void addedge(long long u,long long v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs1(long long x)
    {
        size[x]=1;son[x]=0;
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if (v!=fath[x])
            {
                dis[v]=dis[x]+1;
                fath[v]=x;
                dfs1(v);
                size[x]=size[x]+size[v];
                if (size[v]>size[son[x]]) son[x]=v;
            }
        }    
    }
    void dfs2(long long x,long long father)
    {
        w[x]=++cnt;fw[cnt]=x;top[x]=father;mx[x]=w[x];
        if (son[x]!=0) dfs2(son[x],father);mx[x]=max(mx[x],mx[son[x]]);
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if ((v!=fath[x]) && (v!=son[x]))
            {
                dfs2(v,v);
                mx[x]=max(mx[x],mx[v]);
            }
        }
    }
    void build(long long &now,long long left,long long right)
    {
        now=++tot;value[now]=0;lazy[now]=0;
        if (left==right) 
        {
            value[now]=k[fw[left]];
            return;
        }
        long long mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
        value[now]=value[ls[now]]+value[rs[now]];
    }
    void pushdown(long long now,long long left,long long right)
    {
        if (lazy[now]!=0)
        {
            long long mid=(left+right)>>1;
            lazy[ls[now]]+=lazy[now];
            value[ls[now]]+=lazy[now]*(mid-left+1);
            lazy[rs[now]]+=lazy[now];
            value[rs[now]]+=lazy[now]*(right-mid);
            lazy[now]=0;
        }
    }
    void single_modify(long long now,long long left,long long right,long long pos,long long a)
    {
        pushdown(now,left,right);
        if ((left==right) && (left==pos))
        {
            value[now]+=a;
            return;
        }
        long long mid=(left+right)>>1;
        if (pos<=mid) single_modify(ls[now],left,mid,pos,a);
        else single_modify(rs[now],mid+1,right,pos,a);
        value[now]=value[ls[now]]+value[rs[now]];
    }
    void big_modify(long long now,long long left,long long right,long long l,long long r,long long a)
    {
        pushdown(now,left,right);
        if ((left==l) && (right==r))
        {
            value[now]+=a*(right-left+1);
            lazy[now]+=a;
            return;
        }
        long long mid=(left+right)>>1;
        if (r<=mid) big_modify(ls[now],left,mid,l,r,a);
        else if (l>=mid+1) big_modify(rs[now],mid+1,right,l,r,a);
        else
        {
            big_modify(ls[now],left,mid,l,mid,a);
            big_modify(rs[now],mid+1,right,mid+1,r,a);
        }
        value[now]=value[ls[now]]+value[rs[now]];
    }
    long long ask(long long now,long long left,long long right,long long l,long long r)
    {
        pushdown(now,left,right);
        if ((left==l) && (right==r))
            return value[now];
        long long mid=(left+right)>>1;
        if (r<=mid) return ask(ls[now],left,mid,l,r);
        else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r);
        else return ask(ls[now],left,mid,l,mid)+ask(rs[now],mid+1,right,mid+1,r);
    }
    void work1()
    {
        long long a;
        scanf("%lld%lld",&x,&a);
        single_modify(root,1,cnt,w[x],a);
    }
    void work2()
    {
        long long a;
        scanf("%lld%lld",&x,&a);
        big_modify(root,1,cnt,w[x],mx[x],a);
    }
    void work3()
    {
        long long ans=0;
        scanf("%lld",&x);
        long long f1=top[x];
        while (f1!=1)
        {
            ans=ans+ask(root,1,cnt,w[f1],w[x]);
            x=fath[f1];
            f1=top[x];
        }
        ans=ans+ask(root,1,cnt,w[1],w[x]);
        printf("%lld
    ",ans);
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for (long long i=1;i<=n;i++)
            scanf("%lld",&k[i]);
        for (long long i=1;i<=n-1;i++)
        {
            scanf("%lld%lld",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        dfs1(1);
        dfs2(1,1);
        build(root,1,cnt);
        for (long long i=1;i<=m;i++)
        {
            scanf("%lld",&type);
            if (type==1) work1();
            else if (type==2) work2();
            else work3();
        }
        return 0;
    }
  • 相关阅读:
    mac c++编译出现segmentation fault :11错误
    ssh 连接缓慢解决方法
    237. Delete Node in a Linked List
    203. Remove Linked List Elements
    Inversion of Control Containers and the Dependency Injection pattern
    82. Remove Duplicates from Sorted List II
    83. Remove Duplicates from Sorted List
    SxsTrace
    使用CCleaner卸载chrome
    decimal and double ToString problem
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5303464.html
Copyright © 2011-2022 走看看