线段树区修区查求和求调
  • 板块学术版
  • 楼主Xwty
  • 当前回复20
  • 已保存回复20
  • 发布时间2024/7/1 13:20
  • 上次更新2024/7/1 16:17:38
查看原帖
线段树区修区查求和求调
927883
Xwty楼主2024/7/1 13:20

题目大意就是区间修改,让这个区间都加v,然后查询一个区间的和。本人线段树写挂了,求调,悬2关

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+!0;
int sum[N<<2];
int add[N<<2];
int a[N];

void build(int l,int r,int x)
{
	if(l==r)
	{
		sum[x]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,x*2);
	build(mid+1,r,x*2+1);
	sum[x]=sum[2*x]+sum[2*x+1];
}

void pushdown(int l,int r,int x)
{
	int mid=(l+r)>>1;
	if(add[x])
	{
		add[x<<1]=add[x];
		sum[x<<1]+=(mid-l+1)*add[x];
		add[x*2+1]=add[x];
		sum[x*2+1]+=(r-mid)*add[x];
		add[x]=0;
	}
}

void modify(int L,int R,int value,int l,int r,int x)
{
	if(L<=l&&r<=R)
	{
		sum[x]+=(r-l+1)*value;
		add[x]+=value;
		return;
	}
	pushdown(l,r,x);
	int mid=(l+r)>>1;
	if(L<mid) modify(L,R,value,l,mid,x*2);
	if(R>mid) modify(L,R,value,mid+1,r,x*2+1);
	sum[x]=sum[x*2]+sum[x*2+1];
}

int query(int L,int R,int l,int r,int x)
{
	if(L<=l&&r<=R)
	{
		return sum[x];
	}
	int mid=(l+r)>>1;
	pushdown(l,r,x);
	int ret=0;
	if(L<=mid) ret+=query(L,R,l,mid,x*2);
	if(R>mid) ret+=query(L,R,mid+1,r,x*2+1);
	return ret;
}

int main()
{
	int n,m;
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	build(1,n,1);
	cin>>m;
	while(m--)
	{
		char op[3];
		scanf("%s",op);
		if(op[0]=='C')
		{
			int x,y,v;
			cin>>x>>y>>v;
			modify(x,y,v,1,n,1);
		}
		else
		{
			int x,y;
			cin>>x>>y;
			int ans=query(x,y,1,n,1);
			cout<<ans<<endl;
		}
	}
	return 0;
}
2024/7/1 13:20
加载中...