分块洛谷30 loj100 求助
查看原帖
分块洛谷30 loj100 求助
723378
鱼跃于渊鸢飞戻天楼主2023/7/14 14:05

rtrt

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int n,q,mod,k,tot,a[N];
int L[N],R[N],belong[N];
int sum[N],taga[N],tagm[N];
void push_down(int x){
	int nx=belong[x];
	for(int i=L[nx];i<=R[nx];i++)
		a[i]=(a[i]*tagm[nx]+taga[nx])%mod;
	taga[nx]=0;tagm[nx]=1;
}
void add(int l,int r,int x){
	int nl=belong[l],nr=belong[r];
	push_down(l);
	if(nl==nr){
		sum[nl]=(sum[nl]+(r-l+1)*x)%mod;
		for(int i=l;i<=r;i++)
			a[i]=(a[i]+x)%mod;
	}else{
		push_down(r);
		sum[nl]=(sum[nl]+(R[nl]-l+1)*x)%mod;
		for(int i=l;i<=R[nl];i++)
			a[i]=(a[i]+x)%mod;
		sum[nr]=(sum[nr]+(r-L[nr]+1)*x)%mod;
		for(int i=L[nr];i<=r;i++)
			a[i]=(a[i]+x)%mod;
		for(int i=nl+1;i<nr;i++){
			sum[i]=(sum[i]+k*x)%mod;
			taga[i]=(taga[i]+x)%mod;
		}
	}
}
void mul(int l,int r,int x){
	int nl=belong[l],nr=belong[r];
	push_down(l);
	if(nl==nr){
		for(int i=l;i<=r;i++){
			sum[nl]=(sum[nl]+a[i]*(x-1))%mod;
			a[i]=(a[i]*x)%mod; 
		}
	}else{
		push_down(r); 
		for(int i=l;i<=R[nl];i++){
			sum[nl]=(sum[nl]+a[i]*(x-1))%mod;
			a[i]=(a[i]*x)%mod; 
		}
		for(int i=L[nr];i<=r;i++){
			sum[nl]=(sum[nl]+a[i]*(x-1))%mod;
			a[i]=(a[i]*x)%mod;
		}
		for(int i=nl+1;i<nr;i++){
			sum[i]=(sum[i]*x)%mod;
			taga[i]=(taga[i]*x)%mod;
			tagm[i]=(tagm[i]*x)%mod;
		}
	}
}
int query(int l,int r){
	int nl=belong[l],nr=belong[r],ans=0;
	if(nl==nr){
		for(int i=l;i<=r;i++)
			ans=(ans+a[i]*tagm[nl]+taga[nl])%mod;
	}else{
		for(int i=l;i<=R[nl];i++)
			ans=(ans+a[i]*tagm[nl]+taga[nl])%mod;
		for(int i=L[nr];i<=r;i++)
			ans=(ans+a[i]*tagm[nr]+taga[nr])%mod;
		for(int i=nl+1;i<nr;i++)
			ans=(ans+sum[i])%mod;
	}
	return ans;
}
void build(){
	k=sqrt(n);
	tot=n/k+(n%k?1:0);
	for(int i=1;i<=tot;i++){
		L[i]=(i-1)*k+1;
		R[i]=i*k;
		tagm[i]=1;
	}
	R[tot]=n;
	for(int i=1;i<=n;i++){
		belong[i]=(i-1)/k+1;
		sum[belong[i]]=(sum[belong[i]]+a[i])%mod;
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n>>q>>mod;
	for(int i=1;i<=n;i++) cin>>a[i];
	build();
	for(int i=1,op,l,r,x;i<=q;i++){
		cin>>op>>l>>r;
		if(op==2){
			cin>>x;add(l,r,x);
		}else if(op==1){
			cin>>x;mul(l,r,x);
		}else cout<<query(l,r)<<'\n';
	}
	return 0;
}
2023/7/14 14:05
加载中...