zoukankan      html  css  js  c++  java
  • BZOJ4034_树上操作_KEY

    题目传送门

    这道题可以树链剖分+线段树。

    其他操作模板,第二个操作只需要将x~x+size[x]-1区间加值即可。

    code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int read(){
        char c;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
        int x=0,y=1;c=='-'?y=-1:x=c-'0';
        while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';
        return x*y;
    }
    
    const int Maxn=100005;
    
    int N,Q,A[Maxn];
    int head[Maxn],nxt[Maxn<<1],to[Maxn<<1],Cnt;
    void Add(int x,int y){
        to[Cnt]=y;
        nxt[Cnt]=head[x];
        head[x]=Cnt;
        Cnt++;
    }
    
    int Son[Maxn],Size[Maxn],f[Maxn];
    int Dep[Maxn],Dfn[Maxn],Top[Maxn];
    int C;
    void Find(int Now,int Deep,int Bef){
        
        f[Now]=Bef,Dep[Now]=Deep,Size[Now]=1;
            for(int i=head[Now];i!=-1;i=nxt[i]){
                if(to[i]==f[Now])continue;
                Find(to[i],Deep+1,Now);
                Size[Now]+=Size[to[i]];
                if(Size[to[i]]>Size[Son[Now]])
                    Son[Now]=to[i];
            }
        return ;
    }
    void Fs(int Now,int Tp){
        Dfn[Now]=++C,Top[Now]=Tp;
        if(Son[Now])Fs(Son[Now],Tp);
            for(int i=head[Now];i!=-1;i=nxt[i]){
                if(to[i]==Son[Now]||to[i]==f[Now])continue;
                Fs(to[i],to[i]);
            }
        return ;
    }
    
    long long Seg[Maxn<<2],Ade[Maxn<<2];
    void Up(int x){Seg[x]=Seg[x<<1]+Seg[x<<1|1];}
    void Down(int x,long long l,long long r){
        if(!Ade[x])return ;
        Seg[x<<1]+=Ade[x]*l;
        Seg[x<<1|1]+=Ade[x]*r;
        Ade[x<<1]+=Ade[x];
        Ade[x<<1|1]+=Ade[x];
        Ade[x]=0;
    }
    void Updata(int Node,int L,int R,int Ul,int Ur,long long Val){
        if(Ul<=L&&Ur>=R){
            Seg[Node]+=Val*(R-L+1);
            Ade[Node]+=Val;
            return ;
        }
        int Mid=L+R>>1;
        Down(Node,Mid-L+1,R-Mid);
        if(Mid>=Ul)Updata(Node<<1,L,Mid,Ul,Ur,Val);
        if(Mid< Ur)Updata(Node<<1|1,Mid+1,R,Ul,Ur,Val);
        Up(Node);
    }
    long long Query(int Node,int L,int R,int Ql,int Qr){
        if(Ql<=L&&Qr>=R)return Seg[Node];
        int Mid=L+R>>1;
        Down(Node,Mid-L+1,R-Mid);
        long long Ans=0;
        if(Mid>=Ql)Ans+=Query(Node<<1,L,Mid,Ql,Qr);
        if(Mid< Qr)Ans+=Query(Node<<1|1,Mid+1,R,Ql,Qr);
        return Ans;
    }
    long long G(int Node){
        long long Ans=0;
            while(Top[Node]){
                Ans+=Query(1,1,N,Dfn[Top[Node]],Dfn[Node]);
                Node=f[Top[Node]];
            }
        return Ans;
    }
    
    int main()
    {
        memset(head,-1,sizeof head);
        N=read(),Q=read();
            for(int i=1;i<=N;i++)A[i]=read();
            for(int i=1;i<N;i++){
                int x=read(),y=read();
                Add(x,y),Add(y,x);
            }
        Find(1,1,0),Fs(1,1);
            for(int i=1;i<=N;i++)
                Updata(1,1,N,Dfn[i],Dfn[i],A[i]);
            for(int i=1;i<=Q;i++){
                int Type=read(),x=read();
                if(Type==1)Updata(1,1,N,Dfn[x],Dfn[x],read());
                if(Type==2)Updata(1,1,N,Dfn[x],Dfn[x]+Size[x]-1,read());
                if(Type==3)printf("%lld
    ",G(x));
            }
        return 0;
    }
  • 相关阅读:
    大数据概述 106
    编译原理学习随笔 106
    我与ruby第一次接触
    xml在joomla表单中的应用详解
    joomla2.5传统组件开发解析
    joomla2.5开发系列教程原创(1)2.5与1.5异同点
    CSS2简写和常用css总结笔记
    C语言开发php扩展链接库初学
    ruby转战Ubuntu,真折腾?
    joomla搜索功能开发和结果分页探讨
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8606891.html
Copyright © 2011-2022 走看看