rt,目前只要求正确性,卡常到时候我换读优就行了,不需要卡常,求改
#include<bits/stdc++.h>
#define reg register int
#define INF (1<<30)
#define int long long
using namespace std;
int p;
int read(){
int res=0,fs=1; char c=getchar();
while(!(c>='0' && c<='9')){ if(c=='-')fs=-1; c=getchar(); }
while(c>='0' && c<='9')res=res*10+(c^48),c=getchar();
return res*fs;
}
void print(int x){
if(x<0) { putchar('-'); x=-x;}
if(x>9) print(x/10);
putchar(x%10+'0');
}
int S;
int lazy[200005];
int n,cnt,m,a[200005],ans,tmp,l,r,k,z,x[200005],y[200005],id[200005],v[1010];
inline void sh1(int l,int r,int k){
int ll=id[l],rr=id[r];
if(ll==rr){
for(int i=l;i<=r;i++) a[i]+=k,v[ll]+=k;
return ;
}
for(int i=ll+1;i<=rr-1;++i) {
v[i]+=k*(y[i]-x[i]+1);
lazy[i]+=k;
}
for(int i=l;i<=y[ll];++i) a[i]+=k,v[ll]+=k;
for(int i=x[rr];i<=r;++i) a[i]+=k,v[rr]+=k;
}
int lazy2[2020];
inline void sh2(int l,int r,int k){
int ll=id[l],rr=id[r];
if(ll==rr){
for(int i=l;i<=r;i++) v[ll]+=(a[i]*k-a[i]),a[i]*=k,a[i]%=p,v[ll]%=p;
return ;
}
for(int i=ll+1;i<=rr-1;++i) {
v[i]*=k;
v[i]%=p;
if(lazy[i]==0) lazy[i]=k;
else lazy[i]*=k,lazy[i]%=p;
}
for(int i=l;i<=y[ll];++i) v[ll]+=(a[i]*k-a[i]),a[i]*=k,a[i]%=p,v[ll]%=p;
for(int i=x[rr];i<=r;++i) v[rr]+=(a[i]*k-a[i]),a[i]*=k,a[i]%=p,v[rr]%=p;
}
inline int cx(int l,int r){
//l~~r
int ll=id[l],rr=id[r];
int ret=0;
if(ll==rr){
for(int i=l;i<=r;i++) ret+=a[i]+lazy[ll],ret%=p;
return ret;
}
for(int i=ll+1;i<=rr-1;++i) ret+=v[i],ret%=p;
ret%=p;
for(int i=l;i<=y[ll];++i) ret+=a[i]+lazy[id[i]],ret%=p;
ret%=p;
for(int i=x[rr];i<=r;++i) ret+=a[i]+lazy[id[i]],ret%=p;
return ret;
}
signed main() {
// ios::sync_with_stdio(false);
cin>>n>>m>>p;
for(int i=1;i<=n;i++) a[i]=read();
S=sqrt(n);
for(int i=1;i<=S;i++){
x[i]=(i-1)*S+1,y[i]=min(i*S,n);
}
if(x[S]<n) S++,x[S]=y[S-1]+1,y[S]=n;
for(int i=1;i<=S;i++){
for(int j=x[i];j<=y[i];j++) id[j]=i,v[i]+=a[j];
}
while(m--){
int op;
cin>>op;
if(op==2){
cin>>l>>r>>k;
sh1(l,r,k);
}else if(op==1){
cin>>l>>r>>k;
sh2(l,r,k);
}else if(op==3){
cin>>l>>r;
cout<<cx(l,r)%p<<'\n';
}
}
return 0;
}