线段树模板求助!!!
查看原帖
线段树模板求助!!!
112604
Mr__Meng楼主2020/11/14 16:29
#include<bits/stdc++.h>
#define maxn 1000001
#define ll long long
using namespace std;
ll n,m;
ll sum[4*maxn];
ll a[maxn];
ll tag[4*maxn];
ll r()
{
	int f=1,s=0;
	char ch;
	ch=getchar();
	while(ch<'0'||ch>'9')
	{
	    if(ch=='-')
		    f=-1;
		ch=getchar(); 
	}
	while(ch>='0'&&ch<='9')
	{
		s=s*10+ch-'0';
		ch=getchar();
	}
	return f*s;
}
void push_up(ll k)
{
	sum[k]=sum[k*2]+sum[k*2+1];
}
void push_down(ll k,ll l,ll r)
{
	ll mid=(r+l)>>1;
	sum[2*k]+=(mid-l+1)*tag[k];
	tag[2*k]+=tag[k];
	sum[2*k+1]+=(r-mid+1)*tag[k];
	tag[2*k+1]+=tag[k];
	tag[k]=0;
}
void build(ll k,ll l,ll r)
{
	if(l==r)
	{
		sum[l]=a[l];
		return;
	}
	ll mid=(l+r)>>1;
	build(k*2,l,mid);
	build(k*2+1,mid+1,r);
	push_up(k);
}
void update(ll k,ll l,ll r,ll L,ll R,ll dx)
{
	if(L<=l && R>=r)
	{
		sum[k]+=dx*(r-l+1);
		tag[k]+=dx;
		return;
	}
	push_down(k,l,r);
	ll mid=(l+r)>>1;
	update(2*k,l,mid,L,R,dx);
	update(2*k+1,mid+1,r,L,R,dx);
	push_up(k);
}
ll query(ll k,ll l,ll r,ll L,ll R)
{
	ll ans=0;
	if(L>r || R<l)
	    return 0;
	if(L>=l && R>=r)
	    return sum[k];
	push_down(k,l,r);
	ll mid=(r+l)>>1;
	if(L<=mid)ans+=query(2*k,l,mid,L,R);
	if(R>mid)ans+=query(2*k+1,mid+1,r,L,R);
	return ans;
}
void scan()
{
	n=r(),m=r();
	for(ll i=1;i<=n;i++)
	    a[i]=r(); 
}
int main()
{
	scan();
	build(1,1,n);
	for(ll i=1;i<=m;i++)
	{
		ll s;
		s=r();
		if(s==1)
		{
			ll x,y,z;
			x=r(),y=r(),z=r();
			update(1,1,n,x,y,z);
		}
		if(s==2)
		{
			ll x,y;
			x=r();
			y=r();
			printf("%lld\n",query(1,1,n,x,y));
		}
	}
	return 0;
}
2020/11/14 16:29
加载中...