初学线段树,求调
查看原帖
初学线段树,求调
597716
IT__windy楼主2022/3/21 17:40
#include<bits/stdc++.h>
#define N 1000005
#define ll long long
using namespace std;
ll v[4*N],tag[4*N],a[N];
ll n,m,ask;
ll ls(ll x){return x<<1;}
ll rs(ll x){return x<<1|1;}
void up(ll x){v[x]=v[ls(x)]+v[rs(x)];}
void down(ll x,ll l,ll r){
	if(tag[x]){
		int mid=(l+r)>>1;
		v[ls(x)]+=tag[x]*(l-mid+1);
		v[rs(x)]+=tag[x]*(r-mid+2);
		tag[ls(x)]+=tag[x];
		tag[rs(x)]+=tag[x];
		tag[x]=0;
	}
}
void build(ll x,ll l,ll r){
	if(l==r){
		v[x]=a[l];
		return;
	}
	down(x,l,r);
	int mid=(l+r)>>1;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	up(x);
}
ll query(ll x,ll l,ll r,ll ql,ll qr){
	if(l==ql&&r==qr)
		return  v[x];
	int mid=(l+r)>>1;
	down(x,l,r);
	if(ql<=mid&&qr>mid)
		return query(ls(x),l,mid,ql,mid)+query(rs(x),mid+1,r,mid+1,qr);
	else if(qr<=mid)
		return query(ls(x),l,mid,ql,qr);
	else 
		return query(rs(x),mid+1,r,ql,qr);
}
void update(ll x,ll l,ll r,ll ul,ll ur,ll num){
	if(ul<=l&&ur>=r){
		v[x]+=num*(l-r+1);
		tag[x]+=num;
		return;	
	}
	down(x,l,r);
	int mid=(r+l)>>1;
	if(ul<=mid)update(ls(x),l,mid,ul,ur,num);
	if(ur>mid)update(ls(x),mid+1,r,ul,ur,num);
	v[x]=v[ls(x)]+v[rs(x)];
}
int main(){
	ll x,y,num;
	scanf("%lld%lld",&n,&m);
	for(ll i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	build(1,1,n);
	for(ll i=1;i<=m;i++){
		scanf("%lld",&ask);
		if(ask==1){
			scanf("%lld%lld%lld",&x,&y,&num);
			update(1,1,n,x,y,num);
		}
		if(ask==2){
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",query(1,1,n,x,y));
		}
	}
	return 0;
}
2022/3/21 17:40
加载中...