• 牛客小白月赛24 I求和


    链接:https://ac.nowcoder.com/acm/contest/5158/I
    来源:牛客网

     

     

     

    树链剖分的板子题,这里就介绍一篇树链剖分入门的博客吧:https://blog.csdn.net/qq_43326267/article/details/89791152

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+5;
    typedef long long ll;
    struct st{
        int to,next;
    }stm[maxn*2];int head[maxn],cnt;
    void add(int u,int v){
        stm[cnt].to=v;
        stm[cnt].next=head[u];
        head[u]=cnt++;
    }
    ll a[maxn];
    int tsize[maxn],tson[maxn],top[maxn],rk[maxn],id[maxn],dep[maxn],pre[maxn],co;
    void init(int n){
    	for(int i=1;i<=n;i++){
     			head[i]=-1;
       		 	tson[i]=0;
    		}
    		co=cnt=0;
    }
    struct trem{
        ll sum;
    }tre[maxn<<2];
    void dfs1(int now,int fa,int d){
        tsize[now]=1;
        pre[now]=fa;
        dep[now]=d;
    //  cout<<now<<endl;
        for(int i=head[now];~i;i=stm[i].next){
            int to=stm[i].to;
            if(to==fa)continue;
            dfs1(to,now,d+1);
            tsize[now]+=tsize[to];
            if(tsize[to]>tsize[tson[now]])tson[now]=to;
        }
    }
    void dfs2(int now,int Top){
        rk[++co]=now;
        id[now]=co;//编号->dfs序
        top[now]=Top;
        if(tson[now]>0)
        dfs2(tson[now],Top);
        for(int i=head[now];~i;i=stm[i].next){
            int to=stm[i].to;
            if(to==pre[now]||to==tson[now])continue;
            dfs2(to,to);
        }
    }
    void pushup(int rt){
        tre[rt].sum=tre[rt<<1].sum+tre[rt<<1|1].sum;
        return ;
    }
    void build(int l,int r,int rt){
        if(l==r){
            tre[rt].sum=a[rk[l]];
            return ;
        }
        int mid=(l+r)/2;
        build(l,mid,rt<<1);
        build(mid+1,r,rt<<1|1);
        pushup(rt);
    }
    ll query(int l,int r,int lm,int rm,int rt){
        if(l<=lm&&r>=rm){
            return tre[rt].sum;
        }
        ll ans=0;
        int mid=(lm+rm)/2;
        if(l<=mid)ans+=query(l,r,lm,mid,rt<<1);
        if(r>mid)ans+=query(l,r,mid+1,rm,rt<<1|1);
        return ans;
    }
    void update(int l,int r,int pos,ll num,int rt){
        if(l==r){
            tre[rt].sum+=num;
            return ;
        }
        int mid=(l+r)/2;
        if(mid>=pos)update(l,mid,pos,num,rt<<1);
        else update(mid+1,r,pos,num,rt<<1|1);
        pushup(rt);
        return ;
    }
    int main(){
        int n,m,k;
        int u,v;
        scanf("%d%d%d",&n,&m,&k);
        init(n);
    	
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }    
        dfs1(k,-1,0);
        dfs2(k,k);
        build(1,n,1);
        int op,pos;
        ll num;
        for(int i=1;i<=m;i++){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%lld",&pos,&num); 
                update(1,n,id[pos],num,1);
            }
            else{
                scanf("%d",&pos);
                printf("%lld
    ",query(id[pos],id[pos]+tsize[pos]-1,1,n,1));
            }
        }
        return 0;
    }
    

      

      

  • 相关阅读:
    Ztree下拉框多选
    FullCalendar日程插件
    viscose 前端常用插件
    一些词
    关于require()和export引入依赖的区别
    关于CMD/AMD和Common.js/Sea.js/Require.js
    vue中的双向数据绑定原理简单理解
    Vue-cli简单使用
    webpack简单配置
    vuex基础
  • 原文地址:https://www.cnblogs.com/Zhi-71/p/12731131.html
Copyright © 2020-2023  润新知