RT,本人刚学线段树不久一直搞不出来,long long也开了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll n,q,ask,x,y,k,mod,a[N],tag[N<<2],val[N<<2],tag2[N<<2];
inline ll ls(ll o){
return o<<1;
}
inline ll rs(ll o){
return o<<1|1;
}
inline ll read(){//快读
ll x=0,flag=1;
char ch=getchar();
while(ch<'0'||ch>'9') flag^=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*flag;
}
inline void write(ll x){//快输
if(x<0){
putchar('-');
x=~(x-1);
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void build(ll o,ll l,ll r){//建树
tag2[o]=1,tag[o]=0;
if(l==r){
val[o]=a[l];
return;
}
ll mid=(l+r)>>1;
build(ls(o),l,mid);
build(rs(o),mid+1,r);
val[o]=(val[ls(o)]+val[rs(o)])%mod;
}
inline void pushdown(ll o,ll l,ll r){//处理加法懒标记
ll mid=(l+r)>>1;
tag[ls(o)]+=tag[o],tag[ls(o)]%=mod,val[ls(o)]+=tag[o]*(mid-l+1)%mod,val[ls(o)]%=mod;
tag[rs(o)]+=tag[o],tag[rs(o)]%=mod,val[rs(o)]+=tag[o]*(r-mid)%mod,val[rs(o)]%=mod;
tag[o]=0;
}
inline void pushdown2(ll o,ll l,ll r){//处理乘法懒标记
ll mid=(l+r)>>1;
tag2[ls(o)]*=tag2[o],val[ls(o)]*=tag2[o],val[ls(o)]%=mod;
tag2[rs(o)]*=tag2[o],val[rs(o)]*=tag2[o],val[rs(o)]%=mod;
tag[ls(o)]*=tag2[o],tag[ls(o)]%=mod,tag[rs(o)]*=tag2[o],tag[rs(o)]%=mod;//把加法懒标记也处理
tag2[o]=1;
}
inline void update(ll o,ll l,ll r,ll s,ll t,ll x){//处理区间加
if(s<=l&&r<=t){
val[o]+=x*(r-l+1)%mod,val[o]%=mod,tag[o]+=x,tag[o]%=mod;
return;
}
ll mid=(l+r)>>1;
pushdown2(o,l,r);pushdown(o,l,r);
if(s<=mid) update(ls(o),l,mid,s,t,x);
if(t>mid) update(rs(o),mid+1,r,s,t,x);
val[o]=(val[ls(o)]+val[rs(o)])%mod;
}
inline void update2(ll o,ll l,ll r,ll s,ll t,ll x){//处理区间乘
if(s<=l&&r<=t){
val[o]*=x,val[o]%=mod,tag2[o]*=x,tag[o]*=x,tag[o]%=mod,tag2[o]%=mod;
return;
}
ll mid=(l+r)>>1;
pushdown2(o,l,r);pushdown(o,l,r);
if(s<=mid) update2(ls(o),l,mid,s,t,x);
if(t>mid) update2(rs(o),mid+1,r,s,t,x);
val[o]=(val[ls(o)]+val[rs(o)])%mod;
}
inline ll query(ll o,ll l,ll r,ll s,ll t){//询问
if(s<=l&&t>=r) return val[o]%mod;
pushdown2(o,l,r);pushdown(o,l,r);
ll mid=(l+r)>>1,res=0;
if(s<=mid) res+=query(ls(o),l,mid,s,t)%mod,res%=mod;
if(t>mid) res+=query(rs(o),mid+1,r,s,t)%mod,res%=mod;
return res%mod;
}
int main(){
n=read(),q=read(),mod=read();
for(ll i=1;i<=n;i++) a[i]=read();
build(1,1,n);
while(q--){
ask=read(),x=read(),y=read();
if(ask==1){
k=read()%mod;
update2(1,1,n,x,y,k);
}
if(ask==2){
k=read()%mod;
update(1,1,n,x,y,k);
}
if(ask==3){
write(query(1,1,n,x,y));
putchar('\n');
}
}
return 0;
}