可能有些同学看不惯我这个蒟蒻把操作全写结构体里,不过刚开始码风就是这样......反正还是能看的qwq(
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#define MAXN 100005
#define lson(o) (o<<1)
#define rson(o) (o<<1|1)
#define LL long long
using namespace std;
LL a[MAXN],n,m;
LL mod;
inline long long read(){
long long x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
inline void out(long long x){
if(x<0) putchar('-'),x=-x;
if(x>9) out(x/10);
putchar(x%10+'0');
}
struct SMT{
LL sumv[MAXN<<2];
LL plz[MAXN<<2];
LL mlz[MAXN<<2];
inline void pushup(LL o){
sumv[o]=(sumv[rson(o)]+sumv[lson(o)])%mod;
}
inline void pushdown(LL ql,LL qr,LL o){
LL mid=(ql+qr)>>1;
if(plz[o]){
sumv[lson(o)]+=plz[o]*(mid-ql+1);
sumv[lson(o)]%=mod;
sumv[rson(o)]+=plz[o]*(qr-mid);
sumv[rson(o)]%=mod;
plz[lson(o)]+=plz[o];
plz[lson(o)]%=mod;
plz[rson(o)]+=plz[o];
plz[rson(o)]%=mod;
plz[o]=0;
}
if(mlz[o]!=1){
mlz[lson(o)]=mlz[o]*mlz[lson(o)]%mod;
mlz[rson(o)]=mlz[o]*mlz[rson(o)]%mod;
plz[lson(o)]=mlz[o]*plz[lson(o)]%mod;
plz[rson(o)]=mlz[o]*plz[lson(o)]%mod;
sumv[lson(o)]=mlz[o]*sumv[lson(o)]%mod;
sumv[rson(o)]=mlz[o]*sumv[rson(o)]%mod;
mlz[o]=1;
}
return;
}
inline void build(LL l,LL r,LL o){
plz[o]=0;
mlz[o]=1;
if(l==r){
sumv[o]=a[l];
return;
}
LL mid=(l+r)>>1;
build(l,mid,lson(o));
build(mid+1,r,rson(o));
pushup(o);
}
inline void add(LL l,LL r,LL k,LL ql,LL qr,LL o){
if(l<=ql&&qr<=r){
sumv[o]+=k*(qr-ql+1);
sumv[o]%=mod;
plz[o]+=k;
plz[o]%=mod;
return;
}
LL mid=(ql+qr)>>1;
pushdown(ql,qr,o);
if(l<=mid)add(l,r,k,ql,mid,lson(o));
if(r>mid)add(l,r,k,mid+1,qr,rson(o));
pushup(o);
}
inline void mul(LL l,LL r,LL k,LL ql,LL qr,LL o){
if(l<=ql&&qr<=r){
sumv[o]*=k;
sumv[o]%=mod;
plz[o]*=k;
plz[o]%=mod;
mlz[o]*=k;
mlz[o]%=mod;
return;
}
pushdown(ql,qr,o);
LL mid=(ql+qr)>>1;
if(l<=mid)mul(l,r,k,ql,mid,lson(o));
if(r>mid)mul(l,r,k,mid+1,qr,rson(o));
pushup(o);
}
inline LL QrySum(LL l,LL r,LL ql,LL qr,LL o){
LL sum=0;
if(l<=ql&&qr<=r){
return sumv[o];
}
LL mid=(ql+qr)>>1;
pushdown(ql,qr,o);
if(l<=mid)sum+=QrySum(l,r,ql,mid,lson(o));
sum%=mod;
if(r>mid)sum+=QrySum(l,r,mid+1,qr,rson(o));
return sum%mod;
}
};
SMT tree;
int main(){
n=read();
m=read();
mod=read();
for(LL i=1;i<=n;i++){
a[i]=read();
}
tree.build(1,n,1);
while(m--){
LL opt,l,r,k;
opt=read();
l=read();
r=read();
if(opt==1){
k=read();
tree.mul(l,r,k,1,n,1);
}
else if(opt==2){
k=read();
tree.add(l,r,k,1,n,1);
}
else{
printf("%lld\n",tree.QrySum(l,r,1,n,1));
}
}
return 0;
}