求调
查看原帖
求调
1020186
zhouxianzhuo楼主2024/6/10 10:49

思路为分块

简化版(看思路)

#include<bits/stdc++.h>
using namespace std;
long long n,m,bl,t,st[1010],ed[1010],pos[200010],a[200010],b[200010],sa[200010],sb[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]+=k;
		suma[p]+=k*(y-x+1);
		for(int i=x;i<=y;i++)
			sum[p]+=b[i]*k;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			adda[i]+=k;
		for(int i=x;i<=ed[p];i++)
			a[i]+=k;
		suma[p]+=k*(ed[p]-x+1);
		for(int i=x;i<=ed[p];i++)
			sum[p]+=b[i]*k;
		for(int i=st[q];i<=y;i++)
			a[i]+=k;
		suma[q]+=k*(y-st[q]+1);
		for(int i=st[q];i<=y;i++)
			sum[q]+=b[i]*k;
	}
}
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]+=k;
		sumb[p]+=k*(y-x+1);
		for(int i=x;i<=y;i++)
			sum[p]+=a[i]*k;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			addb[i]+=k;
		for(int i=x;i<=ed[p];i++)
			b[i]+=k;
		sumb[p]+=k*(ed[p]-x+1);
		for(int i=x;i<=ed[p];i++)
			sum[p]+=a[i]*k;
		for(int i=st[q];i<=y;i++)
			b[i]+=k;
		sumb[q]+=k*(y-st[q]+1);
		for(int i=st[q];i<=y;i++)
			sum[q]+=a[i]*k;
	}
}
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+=(a[i]+adda[p])*(b[i]+addb[p]);
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			ans+=sum[i]+adda[i]*sumb[i]+addb[i]*suma[i]+adda[i]*addb[i];
		for(int i=x;i<=ed[p];i++)
			ans+=(a[i]+adda[p])*(b[i]+addb[p]);
		for(int i=st[q];i<=y;i++)
			ans+=(a[i]+adda[q])*(b[i]+addb[q]);
	}
	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];
			sumb[i]+=sumb[i]+b[j];
			sum[i]+=a[j]*b[j];
		}
	}
	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;
}

完整版(看细节)

#include<bits/stdc++.h>
using namespace std;
long long n,m,bl,t,st[1010],ed[1010],pos[200010],a[200010],b[200010],sa[200010],sb[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)%998244353;
		suma[p]=(suma[p]+k*(y-x+1)%998244353)%998244353;
		for(int i=x;i<=y;i++)
			sum[p]=(sum[p]+(b[i]*k%998244353))%998244353;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			adda[i]=(adda[i]+k)%998244353;
		for(int i=x;i<=ed[p];i++)
			a[i]=(a[i]+k)%998244353;
		suma[p]=(suma[p]+k*(ed[p]-x+1)%998244353)%998244353;
		for(int i=x;i<=ed[p];i++)
			sum[p]=(sum[p]+(b[i]*k%998244353))%998244353;
		for(int i=st[q];i<=y;i++)
			a[i]=(a[i]+k)%998244353;
		suma[q]=(suma[q]+k*(y-st[q]+1)%998244353)%998244353;
		for(int i=st[q];i<=y;i++)
			sum[q]=(sum[q]+(b[i]*k%998244353))%998244353;
	}
}
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)%998244353;
		sumb[p]=(sumb[p]+k*(y-x+1)%998244353)%998244353;
		for(int i=x;i<=y;i++)
			sum[p]=(sum[p]+(a[i]*k%998244353))%998244353;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			addb[i]=(addb[i]+k)%998244353;
		for(int i=x;i<=ed[p];i++)
			b[i]=(b[i]+k)%998244353;
		sumb[p]=(sumb[p]+k*(ed[p]-x+1)%998244353)%998244353;
		for(int i=x;i<=ed[p];i++)
			sum[p]=(sum[p]+(a[i]*k%998244353))%998244353;
		for(int i=st[q];i<=y;i++)
			b[i]=(b[i]+k)%998244353;
		sumb[q]=(sumb[q]+k*(y-st[q]+1)%998244353)%998244353;
		for(int i=st[q];i<=y;i++)
			sum[q]=(sum[q]+(a[i]*k%998244353))%998244353;
	}
}
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])%998244353)*((b[i]+addb[p])%998244353)%998244353)%998244353;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
			ans=(ans+((sum[i]+(adda[i]*sumb[i]%998244353+addb[i]*suma[i]%998244353)%998244353)%998244353+adda[i]*addb[i]%998244353)%998244353)%998244353;
		for(int i=x;i<=ed[p];i++)
			ans=(ans+((a[i]+adda[p])%998244353)*((b[i]+addb[p])%998244353)%998244353)%998244353;
		for(int i=st[q];i<=y;i++)
			ans=(ans+((a[i]+adda[q])%998244353)*((b[i]+addb[q])%998244353)%998244353)%998244353;
	}
	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])%998244353;
			sumb[i]=(sumb[i]+b[j])%998244353;
			sum[i]=(sum[i]+a[j]*b[j]%998244353)%998244353;
		}
	}
	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/10 10:49
加载中...