#include<bits/stdc++.h>
using namespace std;
const int MAXN=500010;
#define int long long
int n,q,m,a[MAXN];
struct Tree{
int num,add,mul;
}t[MAXN<<2];
void Pushup(int pos){
t[pos].num=t[pos<<1].num%m+t[pos<<1|1].num%m;
return;
}
void build(int pos,int l,int r){
if(l==r){
t[pos]={a[l],0,1};
return;
}
int mid=(l+r)>>1;
build(pos<<1,l,mid);
build(pos<<1|1,mid+1,r);
Pushup(pos);
}
void pushdown(int pos,int l,int r){
if(t[pos].add||t[pos].mul>1){
int mid=(l+r)>>1;
t[pos<<1].add=(t[pos<<1].add%m*t[pos].mul%m+t[pos].add%m)%m;
t[pos<<1].num=(t[pos<<1].num%m*t[pos].mul%m+t[pos].add*(mid-l+1))%m; //t[pos].add%m+(mid-l+1)%m;
t[pos<<1].mul=(t[pos<<1].mul%m*t[pos].mul)%m;
t[pos<<1|1].add=(t[pos<<1|1].add%m*t[pos].mul%m+t[pos].add%m)%m;
t[pos<<1|1].num=(t[pos<<1|1].num%m*t[pos].mul%m+t[pos].add*(r-mid))%m; //t[pos].add%m+(mid-l+1)%m;
t[pos<<1|1].mul=(t[pos<<1|1].mul%m*t[pos].mul)%m;
t[pos].add=0;
t[pos].mul=1;
}
}
void Update(int pos,int l,int r,int k,int ql,int qr){
if(ql<=l&&qr>=r){
t[pos].add+=k%m;
t[pos].num+=k%m*(r-l+1)%m;
return;
}
int mid=(l+r)>>1;
pushdown(pos,l,r);
if(ql<=mid)Update(pos<<1,l,mid,k,ql,qr);
if(qr>mid) Update(pos<<1|1,mid+1,r,k,ql,qr);
Pushup(pos);
return;
}
void update(int pos,int l,int r,int k,int ql,int qr){
cout<<pos<<" "<<l<<" "<<r<<" "<<k<<" "<<ql<<" "<<qr<<endl;
if(ql<=l&&qr>=r){
t[pos].add=t[pos].add*k%m;
t[pos].mul=t[pos].mul*k%m;
t[pos].num=t[pos].num*k%m;
return;
}
int mid=(l+r)>>1;
pushdown(pos,l,r);
if(ql<=mid)Update(pos<<1,l,mid,k,ql,qr);
if(qr>mid) Update(pos<<1|1,mid+1,r,k,ql,qr);
Pushup(pos);
return;
}
int query(int pos,int l,int r,int ql,int qr){
//if(l==r)return t[pos].num;
if(ql<=l&&qr>=r){
return t[pos].num%m;
}
int res=0,mid=(l+r)>>1;
pushdown(pos,l,r);
if(ql<=mid)res+=query(pos<<1,l,mid,ql,qr);
if(qr>mid)res+=query(pos<<1|1,mid+1,r,ql,qr);
return res%m;
}
signed main(){
scanf("%lld%lld%lld",&n,&q,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
a[i]=a[i]%m;
}
build(1,1,n);
for(int i=1;i<=q;i++){
int tmp;
scanf("%lld",&tmp);
if(tmp==1){
int x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
update(1,1,n,k%m,x,y);
}
else if(tmp==2){
int x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
Update(1,1,n,k%m,x,y);
}
else {
int x,y;
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,1,n,x,y)%m);
}
}
return 0;
}
给样例总是输出8和17,调了很久都这样,求助大佬