分块求调 悬关
查看原帖
分块求调 悬关
1020186
zhouxianzhuo楼主2024/6/13 13:13
#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
long long n,m,bl,t,st[1010],ed[1010],pos[200010],a[200010],b[200010],suma[1010],adda[1010],sumb[1010],addb[1010],sum[1010];
void changea(int x,int y,int k){
	int p=pos[x],q=pos[y];
	if(p==q)
	{
		for(int i=x;i<=y;i++)
			a[i]=(a[i]+k)%mod;
		suma[p]=(suma[p]+k*(y-x+1)%mod)%mod;
		for(int i=x;i<=y;i++)
			sum[p]=(sum[p]+b[i]*k%mod)%mod;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			adda[i]=(adda[i]+k)%mod;
		for(int i=x;i<=ed[p];i++)
			a[i]=(a[i]+k)%mod;
		suma[p]=(suma[p]+k*(ed[p]-x+1)%mod)%mod;
		for(int i=x;i<=ed[p];i++)
			sum[p]=(sum[p]+b[i]*k%mod)%mod;
		for(int i=st[q];i<=y;i++)
			a[i]=(a[i]+k)%mod;
		suma[q]=(suma[q]+k*(y-st[q]+1)%mod)%mod;
		for(int i=st[q];i<=y;i++)
			sum[q]=(sum[q]+b[i]*k%mod)%mod;
	}
}
void changeb(int x,int y,int k){
	int p=pos[x],q=pos[y];
	if(p==q)
	{
		for(int i=x;i<=y;i++)
			b[i]=(b[i]+k)%mod;
		sumb[p]=(sumb[p]+k*(y-x+1)%mod)%mod;
		for(int i=x;i<=y;i++)
			sum[p]=(sum[p]+a[i]*k%mod)%mod;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			addb[i]=(addb[i]+k)%mod;
		for(int i=x;i<=ed[p];i++)
			b[i]=(b[i]+k)%mod;
		sumb[p]=(sumb[p]+k*(ed[p]-x+1)%mod)%mod;
		for(int i=x;i<=ed[p];i++)
			sum[p]=(sum[p]+a[i]*k%mod)%mod;
		for(int i=st[q];i<=y;i++)
			b[i]=(b[i]+k)%mod;
		sumb[q]=(sumb[q]+k*(y-st[q]+1)%mod)%mod;
		for(int i=st[q];i<=y;i++)
			sum[q]=(sum[q]+a[i]*k%mod)%mod;
	}
}
long long ask(int x,int y){
	long long ans=0;
	int p=pos[x],q=pos[y];
	if(p==q)
	{
		for(int i=x;i<=y;i++)
			ans=(ans+((a[i]+adda[p])%mod)*((b[i]+addb[p])%mod)%mod)%mod;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			ans=(ans+((sum[i]+(adda[i]*sumb[i]%mod+addb[i]*suma[i]%mod)%mod)%mod+(adda[i]*addb[i]%mod)*(ed[i]-st[i]+1)%mod)%mod)%mod;
		for(int i=x;i<=ed[p];i++)
			ans=(ans+((a[i]+adda[p])%mod)*((b[i]+addb[p])%mod)%mod)%mod;
		for(int i=st[q];i<=y;i++)
			ans=(ans+((a[i]+adda[q])%mod)*((b[i]+addb[q])%mod)%mod)%mod;
	}
	return ans;
}
int main(){
	cin>>n>>m;
	bl=sqrt(n);
	t=n/bl;
	if(n%bl>=1)t+=1;
	for(int i=1;i<=t;i++)
	{
		st[i]=(i-1)*bl+1;
		ed[i]=i*bl;
	}
	ed[t]=n;
	for(int i=1;i<=n;i++)
		pos[i]=(i-1)/bl+1;
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++)
		scanf("%lld",&b[i]);
	for(int i=1;i<=t;i++)
	{
		for(int j=st[i];j<=ed[i];j++)
		{
			suma[i]=(suma[i]+a[j])%mod;
			sumb[i]=(sumb[i]+b[j])%mod;
			sum[i]=(sum[i]+a[j]*b[j]%mod)%mod;
		}
	}
	for(int i=1;i<=m;i++)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int x,y,k;
			scanf("%d%d%d",&x,&y,&k);
			changea(x,y,k);
		}
		else if(op==2)
		{
			int x,y,k;
			scanf("%d%d%d",&x,&y,&k);
			changeb(x,y,k);
		}
		else
		{
			int x,y;
			scanf("%d%d",&x,&y);
			printf("%lld\n",ask(x,y));
		}
	}
	return 0;
}
2024/6/13 13:13
加载中...