样例没过qwq
#include<bits/stdc++.h>
#define int long long
#define maxn 100010
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
using namespace std;
struct SegmentTree{
int point;
int tag_add;
int tag_mul;
};
SegmentTree tree[maxn<<2];
int num[maxn],n,m,mod,op,x,y,k;
void pushup(int p){
tree[p].point=(tree[ls(p)].point+tree[rs(p)].point)%mod;
}
void build(int pl,int pr,int p){
tree[p].tag_mul=1;
if (pl==pr){
tree[p].point=num[pl]%mod;
return;
}
int mid=(pl+pr)>>1;
build(pl,mid,ls(p));
build(mid+1,pr,rs(p));
pushup(p);
}
void addtag(int pl,int pr,int p,int k,bool ismul){
if (ismul){
tree[p].tag_mul*=k;
tree[p].tag_add*=k;
tree[p].point=(tree[p].point*k)%mod;
}else{
tree[p].tag_add+=k;
tree[p].point=(tree[p].point+(pr-pl+1)*k)%mod;
}
}
void pushdown(int pl,int pr,int p){
int mid=(pl+pr)>>1;
addtag(pl,mid,ls(p),tree[p].tag_mul,1);
addtag(mid+1,pr,rs(p),tree[p].tag_mul,1);
addtag(pl,mid,ls(p),tree[p].tag_add,0);
addtag(mid+1,pr,rs(p),tree[p].tag_add,0);
tree[p].tag_mul=1;
tree[p].tag_add=0;
}
void update(int pl,int pr,int p,int l,int r,int k,bool ismul){
if (l<=pl && pr<=r){
addtag(pl,pr,p,k,ismul);
return;
}
pushdown(pl,pr,p);
int mid=(pl+pr)>>1;
if (l<=mid) update(pl,mid,p,l,r,k,ismul);
if (r>mid) update(mid+1,pr,p,l,r,k,ismul);
pushup(p);
}
int query(int pl,int pr,int p,int l,int r){
if (l<=pl && pr<=r) return tree[p].point;
pushdown(pl,pr,p);
int mid=(pl+pr)>>1,ans=0;
if (l<=mid) ans+=query(pl,mid,ls(p),l,r);
if (r>mid) ans+=query(mid+1,pr,rs(p),l,r);
return ans%mod;
}
signed main(){
scanf("%lld%lld%lld",&n,&m,&mod);
for (int i=1;i<=n;i++){
scanf("%lld",&num[i]);
}
build(1,n,1);
for (int i=1;i<=m;i++){
scanf("%lld",&op);
if (op==1){
scanf("%lld%lld%lld",&x,&y,&k);
update(1,n,1,x,y,k,1);
}
if (op==2){
scanf("%lld%lld%lld",&x,&y,&k);
update(1,n,1,x,y,k,0);
}
if (op==3){
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,n,1,x,y));
}
}
return 0;
}