蒟蒻自学分块满江红求调
  • 板块P2357 守墓人
  • 楼主pies_0x
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/6/23 10:09
  • 上次更新2024/6/23 13:31:10
查看原帖
蒟蒻自学分块满江红求调
964645
pies_0x楼主2024/6/23 10:09
#include<cstdio>
#include<cmath>
using namespace std;

#define N 200005
#define sqrtN 450
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define from(i) ((i-1)/size)
#define Rlt(i) (i*size+1)
#define Rrt(i) (min(n,Rlt(i+1)-1))
#define lt(i) Rlt(from(i))
#define rt(i) Rrt(from(i))
#define int long long

int sum[sqrtN],add[sqrtN],from[sqrtN],size;
int a[N];
int n,q;

void modify(int l,int r,int v)
{
	if(from(l)==from(r))
	{
		for(int i=l;i<=r;++i)
			a[i]+=v;
		return;
	}
	for(int i=l;i<=rt(l);++i)
		a[i]+=v;
	if(from(r)-from(l)>1)
		for(int i=from(l)+1;i<=from(r)-1;++i)
			add[i]+=v;
	for(int i=lt(r);i<=r;++i)
		a[i]+=v;
}

int query(int l,int r)
{
	int ans=0;
	if(from(l)==from(r))
	{
		for(int i=l;i<=r;++i)
			ans+=a[i]+add[from(i)];
		return ans;
	}
	for(int i=l;i<=rt(l);++i)
		ans+=a[i]+add[from(i)];
	if(from(r)-from(l)>1)
		for(int i=from(l)+1;i<=from(r)-1;++i)
			ans+=sum[i]+add[i]*(Rrt(i)-Rlt(i)+1);
	for(int i=lt(r);i<=r;++i)
		ans+=a[i]+add[from(r)];
	return ans;
}

signed main()
{
	scanf("%lld%lld",&n,&q);
	size=sqrt(n)+1;
	for(int i=1;i<=n;++i)
	{
		scanf("%lld",&a[i]);
		sum[from(i)]+=a[i];
	}
	while(q--)
	{
		int op;
		scanf("%lld",&op);
		if(op==1)
		{
			int l,r,v;
			scanf("%lld%lld%lld",&l,&r,&v);
			modify(l,r,v);
		}
		else if(op==2)
		{
			int v;
			scanf("%lld",&v);
			modify(1,1,v);
		}
		else if(op==3)
		{
			int v;
			scanf("%lld",&v);
			modify(1,1,-v);
		}
		else if(op==4)
		{
			int l,r;
			scanf("%lld%lld",&l,&r);
			printf("%lld\n",query(l,r));
		}
		else if(op==5)
			printf("%lld\n",query(1,1));
	}
	return 0;
}
2024/6/23 10:09
加载中...