线段树20pts求助
查看原帖
线段树20pts求助
464732
luqyou楼主2022/10/10 15:11
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m;
ll t[100001],sum[100001];
struct node{
	int l,r;
	ll v,tag;
}a[400001];
void build(int u,int L,int R){
	a[u].l=L;
	a[u].r=R;
	a[u].v=sum[R]-sum[L-1];
	if(L!=R){
		int Mid=L+R>>1;
		build(u<<1,L,Mid);
		build((u<<1)|1,Mid+1,R);
	}
}
bool inrange(int L,int R,int l,int r){
	//(L,R) in (l,r) 
	return (l<=L)&&(R<=r);
}
bool outofrange(int L,int R,int l,int r){
	return (L>r)||(R<l);
}
void pushup(int u){
	a[u].v=a[u<<1].v+a[(u<<1)|1].v;
} 
void pushdown(int u){
	int L=a[u].l,R=a[u].r,K=a[u].tag,ls=u<<1,rs=(u<<1)|1,Mid=L+R>>1;
	a[u].tag=0;
	a[ls].tag+=K;
	a[rs].tag+=K;
	a[ls].v+=K*(Mid-L+1);
	a[rs].v+=K*(R-Mid);
}
void maketag(int u,int l,int r,ll k){
	int L=a[u].l,R=a[u].r;
	if(inrange(L,R,l,r)){
		a[u].tag+=k;
		a[u].v+=k*(a[u].r-a[u].l+1);
		if(L!=R) pushdown(u);
	}
	else if(!outofrange(L,R,l,r)){
		maketag(u<<1,l,r,k);
		maketag((u<<1)|1,l,r,k);
		pushup(u);
	}
}
ll search(int u,int l,int r){
	int L=a[u].l,R=a[u].r;
	//printf("%d",u);
	if(a[u].tag&&L!=R){
		pushdown(u);
	}
	if(inrange(L,R,l,r)){
		return a[u].v; 
	}
	else if(!outofrange(L,R,l,r)){
		int mid=l+r>>1;
		return search(u<<1,l,r)+search((u<<1)|1,l,r);
	}
	else return 0;
} 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&t[i]);
		sum[i]=sum[i-1]+t[i];
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int op;
		scanf("%d",&op);
		switch(op){
			case 1:{
				int x,y;
				ll k;
				scanf("%d%d%lld",&x,&y,&k);
				maketag(1,x,y,k);
				break;
			}
			case 2:{
				int x,y;
				scanf("%d%d",&x,&y);
				printf("%lld\n",search(1,x,y)); 
				break;
			}
		}
		/*for(int i=1;i<=2*n-1;i++){
			printf(" %d %d %lld %lld\n",a[i].l,a[i].r,a[i].v,a[i].tag);
		}*/
	}
    return 0;
}
2022/10/10 15:11
加载中...