分块求调
查看原帖
分块求调
664744
_lqs_楼主2023/4/30 13:38
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 100005
int n,m,i,j,ans,mod,len;
int opt,l,r,k,p;
int tag[N],a[N],b[N],w[N],lp[N];
void A1(int l,int r,int k){
	int s=w[l],t=w[r];
	if(s==t){
		for(int i=l;i<=r;i++) b[s]=(b[s]+a[i]*(k-1))%mod,a[i]=(a[i]*k)%mod;
		return;
	}
	for(int i=l;w[i]==s;i++) b[s]=(b[s]+a[i]*(k-1))%mod,a[i]=(a[i]*k)%mod;
	for(int i=r;w[i]==t;i--) b[t]=(b[t]+a[i]*(k-1))%mod,a[i]=(a[i]*k)%mod;
	for(int i=s+1;i<=t-1;i++) tag[i]=(tag[i]*k)%mod,b[i]=(b[i]*k)%mod;//相当于乘上标记 
	return; 
}
void A2(int l,int r,int k){
	int s=w[l],t=w[r];
	if(s==t){
		for(int i=l;i<=r;i++) a[i]=(a[i]+k)%mod,b[s]=(b[s]+k)%mod;
		return;
	}
	for(int i=l;w[i]==s;i++) a[i]=(a[i]+k)%mod,b[s]=(b[s]+k)%mod;
	for(int i=r;w[i]==t;i--) a[i]=(a[i]+k)%mod,b[t]=(b[t]+k)%mod;
	for(int i=s+1;i<=t-1;i++) tag[i]=(tag[i]+k)%mod,b[i]=(b[i]+lp[i]*k)%mod;
	return; 
}
int Q(int l,int r){
	int s=w[l],t=w[r],sum=0;
	if(s==t){
		for(int i=l;i<=r;i++) sum=(sum+a[i]+tag[s])%mod;
		return sum;
	}
	for(int i=l;w[i]==s;i++) sum=(sum+a[i]+tag[s])%mod;
	for(int i=r;w[i]==t;i--) sum=(sum+a[i]+tag[t])%mod;
	for(int i=s+1;i<=t-1;i++) sum=(sum+b[i])%mod;
	return sum;
} 
signed main(){
	scanf("%lld%lld%lld",&n,&m,&mod),len=sqrt(n);
	for(i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		if(i%len==0) w[i]=i/len;
		else w[i]=i/len+1;
		b[w[i]]+=a[i]; 
	}
	for(i=1;i<=n+1;i++){
		if(w[i]!=w[i-1]) lp[w[i-1]]=p,p=0;
		p++;
	}
	for(i=1;i<=m;i++){
		scanf("%lld%lld%lld",&opt,&l,&r);
		if(opt==1){
			scanf("%lld",&k);
			A1(l,r,k);
		}
		if(opt==2){
			scanf("%lld",&k);
			A2(l,r,k);
		}
		if(opt==3) printf("%lld\n",Q(l,r));
	}
	return 0;
}

/*
a[i]->a[i]*k=a[i]+a[i]*(k-1)
*/

对拍了一些小数据也没找出哪里挂了......

2023/4/30 13:38
加载中...