社区讨论

求助分块板子

P2357守墓人参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@loy2esui
此快照首次捕获于
2023/11/14 16:22
2 年前
此快照最后确认于
2023/11/14 17:02
2 年前
查看原帖
rt,36pts,wa 好多点 /kel
CPP
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define bug cout<<"bug\n";
#define int long long
using namespace std;
const int N=2e5+10;
int n,m,a[N],L[N],R[N],s[N],tag[N],id[N];
void upd(int x,int y,int k)
{
	int l=id[x],r=id[y];
	if (l==r)
	{
		for (int i=x;i<=y;i++) s[l]+=k,a[i]+=k;
		return;
	}
	for (int i=x;i<=R[l];i++) s[l]+=k,a[i]+=k;
	for (int i=L[r];i<=y;i++) s[r]+=k,a[i]+=k;
	for (int i=l+1;i<r;i++) s[i]+=k*(R[i]-L[i]+1),tag[i]+=k;
}
int query(int x,int y)
{
	int l=id[x],r=id[y],res=0;
	if (l==r)
	{
		for (int i=x;i<=y;i++) res+=a[i]+tag[i];
		return res;
	}
	for (int i=x;i<=R[l];i++) res+=a[i]+tag[l];
	for (int i=L[r];i<=y;i++) res+=a[i]+tag[r];
	for (int i=l+1;i<r;i++) res+=s[i];
	return res;
}
signed main()
{
//	freopen("hack.in","r",stdin);
//	freopen("dd.out","w",stdout);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for (int i=1;i<=n;i++) cin>>a[i];
	int len=sqrt(n);
	for (int i=1;i<=len;i++)
	{
		L[i]=R[i-1]+1;
		R[i]=len*i;
	}
	if (R[len]<n) ++len,L[len]=R[len-1]+1,R[len]=n;
	for (int i=1;i<=len;i++)
	{
		for (int j=L[i];j<=R[i];j++) id[j]=i,s[i]+=a[j];
//		cout<<L[i]<<" "<<R[i]<<" "<<s[i]<<"\n";
	}
	int op,x,y,k;
	while (m--)
	{
		cin>>op;
		if (op==1)
		{
			cin>>x>>y>>k;
			upd(x,y,k);
		}
		else if (op==2)
		{
			cin>>k;
			a[1]+=k;
			s[1]+=k;
		}
		else if (op==3)
		{
			cin>>k;
			a[1]-=k;
			s[1]-=k;
		}
		else if (op==4)
		{
			cin>>x>>y;
			cout<<query(x,y)<<"\n";
		}
		else cout<<a[1]+tag[1]<<"\n";
	}
}

回复

0 条回复,欢迎继续交流。

正在加载回复...