#include <iostream>
#define int long long
using namespace std;
const int N = 100005;
int n,m,p;
int a[N];
int t[N*4];
int pa[N*4];
int pm[N*4];
// 建树
inline void build(int k,int l,int r){
if(l == r){
t[k] = a[l] % p;
return ;
}
int mid = l + r >> 1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
t[k] = t[k<<1] + t[k<<1|1] % p;
}
inline void apushdown(int k,int l,int r,int mid){
if(!pa[k]) return;
t[k*2] = (t[k*2]+(mid-l+1)*pa[k])%p;
pa[k*2] = (pa[k*2]+pa[k])%p;
t[k*2+1] = (t[k*2+1]+(r-mid)*pa[k])%p;
pa[k*2+1] = (pa[k*2+1]+pa[k])%p;
pa[k] = 0;
}
inline void mpushdown(int k,int l,int r,int mid){
if(!pm[k]) return;
t[k*2] = (t[k*2]*(mid-l+1)*pm[k])%p;
pm[k*2] = (pm[k*2]*pm[k])%p;
t[k*2+1] = (t[k*2+1]*(r-mid)*pm[k])%p;
pm[k*2+1] = (pm[k*2+1]*pm[k])%p;
pm[k] = 0;
}
// 询问
inline int query(int k,int l,int r,int x,int y){
if(l <= x && y <= r){
return t[k];
}
int res = 0;
int mid = l + r >> 1;
apushdown(k,l,r,mid);
mpushdown(k,l,r,mid);
if(x <= mid) res = res + query(k<<1,x,mid,x,y) % p;
if(mid < y) res = res + query(k<<1|1,mid+1,y,x,y) % p;
return res % p;
}
// 加法
inline void add(int k,int l,int r,int x,int y,int v){
if(x <= l && y >= r){
t[k] = (t[k]+(r-l+1)*v)%p;
pa[k] = (pa[k]+v)%p;
return ;
}
int mid = l + r >> 1;
apushdown(k,l,r,mid);
if(x <= mid) add(k*2,l,mid,x,y,v);
if(y > mid) add(k*2+1,mid+1,r,x,y,v);
t[k] = (t[k*2] + t[k*2+1]) % p;
}
// 乘法
inline void mul(int k,int l,int r,int x,int y,int v){
if(x <= l && y >= r){
t[k] = (t[k]*(r-l+1)*v)%p;
pm[k] = (pm[k]*v)%p;
return ;
}
int mid = l + r >> 1;
mpushdown(k,l,r,mid);
if(x <= mid) mul(k*2,l,mid,x,y,v);
if(y > mid) mul(k*2+1,mid+1,r,x,y,v);
t[k] = t[k*2] + t[k*2+1] % p;
}
signed main() {
cin >> n >> m >> p;
for(int i = 1; i <= n; i++)
cin >> a[i];
build(1,1,n);
int z,x,y,k;
while(m--){
cin >> z >> x >> y;
// 询问直接输出
// 乘除还要读入一个数
if(z == 3){
cout << query(1,1,n,x,y) << endl;
}else{
cin >> k;
if(z == 1){
add(1,1,n,x,y,k);
}else{
mul(1,1,n,x,y,k);
}
}
}
return 0;
}
写崩了,没经验,真的调不下去,谢谢