动态开点线段树

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<queue>
using namespace std;
const int N=1000005;
int n,m,root=1,cnt=1,lson[N],rson[N],lazy[N<<2],sum[N<<2];
int getson(int &pos){
    if(pos==0){
		pos=++cnt;
	}
    return pos;
}
void pushup(int pos){
    sum[pos]=sum[lson[pos]]+sum[rson[pos]];
}
void pushdown(int pos,int l,int r){
	int mid=(l+r)/2;
    sum[getson(lson[pos])]+=(mid-l+1)*lazy[pos];
    sum[getson(rson[pos])]+=(r-mid)*lazy[pos];
    lazy[lson[pos]]+=lazy[pos];
    lazy[rson[pos]]+=lazy[pos];
    lazy[pos]=0;
}
void update(int &pos,int l,int r,int ql,int qr,int C){
    if(pos==0){
		pos=++cnt;
	}
    if(lazy[pos]!=0){
		pushdown(pos,l,r);
    }
    if(ql<=l && qr>=r){
        sum[pos]+=(r-l+1)*C;
        lazy[pos]+=C;
        return;
    }
	int mid=(l+r)/2;
    if(ql<=mid){
		update(lson[pos],l,mid,ql,qr,C);
	}
    if(qr>mid){
		update(rson[pos],mid+1,r,ql,qr,C);
	}
    pushup(pos);
}
int Query(int pos,int l,int r,int ql,int qr){
    if(pos==0){
		return 0;
	}
    if(lazy[pos]){
		pushdown(pos,l,r);
	}
    if(ql<=l&&qr>=r){
        return sum[pos];
    }
    int ans=0;
	int mid=(l+r)/2;
    if(ql<=mid){
		ans+=Query(lson[pos],l,mid,ql,qr);
	}
    if(qr>mid){
		ans+=Query(rson[pos],mid+1,r,ql,qr);
	}
    pushup(pos);
    return ans;
}
int main(){
	int a,opt,l,r,v;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a);
        update(root,1,n,i,i,a);
    }
    for(int j=1;j<=m;j++){
		scanf("%d",&opt);
        if(opt==1){
            scanf("%d%d%d",&l,&r,&v);
            update(root,1,n,l,r,v);
        }
        else{
            scanf("%d%d",&l,&r);
            printf("%d\n",Query(root,1,n,l,r));
        }
    }
    return 0;
}
posted @ 2019-08-06 15:31  prestige  阅读(252)  评论(0编辑  收藏  举报