代码:
#include<bits/stdc++.h>
#define int long long
#define ls p<<1
#define rs p<<1|1
using namespace std;
int mod,a[100005],n,m;
struct node{
int sum,add,mul;
}tr[400005];
void bt(int p,int l,int r){
tr[p].mul=1;
tr[p].add=0;
if(l==r){
tr[p].sum=a[l]%mod;
return;
}
int mid=(l+r)/2;
bt(ls,l,mid);
bt(rs,mid+1,r);
tr[p].sum=(tr[ls].sum+tr[rs].sum)%mod;
return;
}
void pd(int p,int l,int r){
int mid=(l+r)/2;
tr[ls].sum=(tr[ls].sum*tr[p].mul+tr[p].add*(mid-l+1))%mod;
tr[rs].sum=(tr[rs].sum*tr[p].mul+tr[p].add*(r-mid))%mod;
tr[ls].mul=(tr[ls].mul*tr[p].mul)%p;
tr[rs].mul=(tr[rs].mul*tr[p].mul)%p;
tr[ls].add=(tr[ls].add*tr[p].mul+tr[p].add)%p;
tr[rs].add=(tr[rs].add*tr[p].mul+tr[p].add)%p;
tr[p].mul=1;
tr[p].add=0;
}
void upt(int p,int L,int R,int l,int r,int k){
if(r<L||R<l){
return;
}
if(l<=L&&R<=r){
tr[p].sum=(tr[p].sum*k)%p;
tr[p].mul=(tr[p].mul*k)%p;
tr[p].add=(tr[p].add*k)%p;
return;
}
pd(p,L,R);
int mid=(L+R)/2;
upt(ls,L,mid,l,r,k);
upt(rs,mid+1,R,l,r,k);
tr[p].sum=(tr[ls].sum+tr[rs].sum)%mod;
return ;
}
void upt2(int p,int L,int R,int l,int r,int k){
if(r<L||R<l){
return ;
}
if(l<=L&&R<=r){
tr[p].add=(tr[p].add+k)%mod;
tr[p].sum=(tr[p].sum+k*(R-L+1))%mod;
return;
}
pd(p,L,R);
int mid=(L+R)/2;
upt2(ls,L,mid,l,r,k);
upt2(rs,mid+1,R,l,r,k);
tr[p].sum=(tr[ls].sum+tr[rs].sum)%mod;
return ;
}
int query(int p, int L, int R, int l, int r){
if(r<L||R<l){
return 0;
}
if(l<=L&&R<=r){
return tr[p].sum;
}
pd(p,L,R);
int mid=(L+R)/2;
return (query(ls,L,mid,l,r)+query(rs,mid+1,R,l,r))%mod;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>mod;
for(int i=1;i<=n;i++)cin>>a[i];
bt(1,1,n);
while(m--){
int op,x,y,k;
cin>>op>>x>>y;
if(op==1){
cin>>k;
upt(1,1,n,x,y,k);
}
if(op==2){
cin>>k;
upt2(1,1,n,x,y,k);
}
if(op==3){
cout<<query(1,1,n,x,y)<<"\n";
}
}
}