感谢大佬orz
#include<bits/stdc++.h>
using namespace std;
struct Tree{
long long num,add,mul;
}t[400005];
int n,m,mod,x,y;
long long a[100005],v;
void build(int o,int l,int r){
t[o].mul=1;
t[o].add=0;
if(l==r){
t[o].num=a[l];
return ;
}
int mid=l+r>>1;
build(o*2,l,mid);
build(o*2+1,mid+1,r);
t[o].num=(t[o*2].num+t[o*2+1].num)%mod;
}
void pushdown(int o,int l,int r){
int mid=l+r>>1;
t[o*2].num=(t[o*2].num*t[o].mul+(mid-l+1)*t[o].add)%mod;
t[o*2+1].num=(t[o*2+1].num*t[o].mul+(r-mid)*t[o].add)%mod;
t[o*2].mul=t[o*2].mul*t[o].mul%mod;
t[o*2+1].mul=t[o*2+1].mul*t[o].mul%mod;
t[o*2].add=(t[o*2].add+t[o].add)%mod;
t[o*2+1].add=(t[o*2+1].add+t[o].add)%mod;
t[o].mul=1;
t[o].add=0;
}
void update_add(int o,int l,int r){
if(x<=l&&r<=y){
t[o].num=(t[o].num+(r-l+1)*v)%mod;
t[o].add=(t[o].add+v)%mod;
return ;
}
int mid=l+r>>1;
pushdown(o,l,r);
if(x<=mid) update_add(o*2,l,mid);
if(y>mid) update_add(o*2+1,mid+1,r);
t[o].num=(t[o*2].num+t[o*2+1].num)%mod;
}
void update_mul(int o,int l,int r){
if(x<=l&&r<=y){
t[o].num=t[o].num*v%mod;
t[o].mul=t[o].mul*v%mod;
t[o].add=t[o].add*v%mod;
return ;
}
int mid=l+r>>1;
pushdown(o,l,r);
if(x<=mid) update_mul(o*2,l,mid);
if(y>mid) update_mul(o*2+1,mid+1,r);
t[o].num=(t[o*2].num+t[o*2+1].num)%mod;
}
long long check(int o,int l,int r){
if(x<=l&&r<=y){
return t[o].num;
}
int mid=l+r>>1;
pushdown(o,l,r);
long long ans=0;
if(x<=mid) ans=(ans+check(o*2,l,mid))%mod;
if(y>mid) ans=(ans+check(o*2+1,mid+1,r))%mod;
return ans;
}
int main(){
scanf("%d%d%d",&n,&m,&mod);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,1,n);
while(m--){
int u;
scanf("%d",&u);
if(u==1){
scanf("%d%d%lld",&x,&y,&v);
update_mul(1,1,n);
}
if(u==2){
scanf("%d%d%lld",&x,&y,&v);
update_add(1,1,n);
}
if(u==3){
scanf("%d%d",&x,&y);
cout<<check(1,1,n)<<endl;
}
}
return 0;
}