线段树WA10求助
查看原帖
线段树WA10求助
356003
Moeebius楼主2021/10/6 19:08
#include<bits/stdc++.h>
#define MAXN 100000
#define ll long long
using namespace std;
ll n,m;
ll a[MAXN],addv[MAXN<<2],sum[MAXN<<2];
void build(int o, int l, int r)//建树
{
	if(l==r) sum[o]=a[l];
	else
	{
		int mid=l+(r-l)/2;
		build(o*2,l,mid);
		build(o*2+1,mid+1,r);
		sum[o]=sum[o*2]+sum[o*2+1];
	}
}

void check(int o, int l, int r)//维护
{
	sum[o]=0;
	int lc=o*2,rc=o*2+1;
	if(l<r)
	{
		sum[o]+=sum[lc]+sum[rc];
	}
	sum[o]+=addv[o]*(r-l+1);
}

void add(int o, int l, int r, int pl, int pr, int v)//区间加
{
	int lc=o*2,rc=o*2+1;
	if(pl<=l && r<=pr)
	{
		addv[o]+=v;
	}
	else
	{
		int mid=l+(r-l)/2;
		if(pl<=mid) add(lc,l,mid,pl,pr,v);
		if(pr>mid) add(rc,mid+1,r,pl,pr,v);
	}
	check(o,l,r);
}

int _sum;
void query(int o, int l, int r, int pl, int pr, int add)//区间查询
{
	//cout<<l<<' '<<r<<endl;
	if(pl<=l && r<=pr)
	{
		_sum+=sum[o]+add*(r-l+1);
		//cout<<"hhh\n";
	}
	else
	{
		int mid=l+(r-l)/2;
		if(pl<=mid) query(o*2, l, mid, pl, pr, add+addv[o]);
		if(pr>mid) query(o*2+1, mid+1, r, pl, pr, add+addv[o]);
	}
}

int main(int argc, char const *argv[])
{
	cin>>n>>m;
	for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
	build(1,1,n);
	//for(int i=1; i<n<<2; i++) printf("%lld ",sum[i]);
	for(int i=1; i<=m; i++)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int u,v,w;
			scanf("%d %d %d",&u,&v,&w);
			add(1,1,n,u,v,w);
		}
		else 
		{
			int u,v;
			scanf("%d %d",&u,&v);
			_sum=0;
			query(1,1,n,u,v,0);
			cout<<_sum<<endl;
		}
	}
	return 0;
}
2021/10/6 19:08
加载中...