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;
    }
  • 相关阅读:
    wex5 实战 框架拓展之2 事件派发与data刷新
    wex5 实战 框架拓展之1 公共data组件(Data)
    wex5 实战 HeidiSQL 导入Excel数据
    wex5 实战 手指触屏插件 hammer的集成与优劣
    wex5 实战 登陆帐号更换与用户id一致性
    wex5 实战 用户点评与提交设计技巧
    wex5 实战 省市县三级联动与地址薄同步
    wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)
    wex5 实战 单页模式下的多页面数据同步
    [BZOJ]4237: 稻草人
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8606891.html
Copyright © 2011-2022 走看看