Rt,求调
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5 + 1e2;
int n,m,mod,a[maxn];
struct segmentTree{
int sum[maxn << 2] = {0},add[maxn << 2] = {0},mul[maxn << 2] = {1};
inline void pushup(int t){
sum[t] = (sum[t << 1] + sum[t << 1 | 1]) % mod;
return;
}
inline void pushdown(int l,int r,int t){
int mid = l + r >> 1;
mul[t << 1] = mul[t << 1] * mul[t] % mod;
mul[t << 1 | 1] = mul[t << 1 | 1] * mul[t] % mod;
add[t << 1] = (add[t << 1] * mul[t] + add[t]) % mod;
add[t << 1 | 1] = (add[t << 1 | 1] * mul[t] + add[t]) % mod;
sum[t << 1] = (sum[t << 1] * mul[t] % mod + add[t] * (mid - l + 1) % mod) % mod;
sum[t << 1 | 1] = (sum[t << 1 | 1] * mul[t] % mod + add[t] * (r - mid) % mod) % mod;
mul[t] = 1;
add[t] = 0;
return;
}
void build(int l,int r,int t){
if(l == r){
sum[t] = a[l] % mod;
return;
}
int mid = l + r >> 1;
build(l,mid,t << 1);
build(mid + 1,r,t << 1 | 1);
pushup(t);
return;
}
int query(int l,int r,int L,int R,int t){
if(L <= l && r <= R) return sum[t];
pushdown(l,r,t);
int mid = l + r >> 1,s = 0;
if(mid >= L) s = (s + query(l,mid,L,R,t << 1)) % mod;
if(mid < R) s = (s + query(mid + 1,r,L,R,t << 1 | 1)) % mod;
return s;
}
void updateAdd(int l,int r,int L,int R,int t,int k){
if(L <= l && r <= R){
add[t] = (add[t] + k) % mod;
sum[t] = (sum[t] + k * (r - l + 1)) % mod;
return;
}
pushdown(l,r,t);
int mid = l + r >> 1;
if(mid >= L) updateAdd(l,mid,L,R,t << 1,k);
if(mid < R) updateAdd(mid + 1,r,L,R,t << 1 | 1,k);
pushup(t);
return;
}
void updateMul(int l,int r,int L,int R,int t,int k){
if(L <= l && r <= R){
add[t] = add[t] * k % mod;
mul[t] = mul[t] * k % mod;
sum[t] = sum[t] * k % mod;
return;
}
pushdown(l,r,t);
int mid = l + r >> 1;
if(mid >= L) updateMul(l,mid,L,R,t << 1,k);
if(mid < R) updateMul(mid + 1,r,L,R,t << 1 | 1,k);
pushup(t);
return;
}
}tree;
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];
}
tree.build(1,n,1);
for(int i = 1;i <= m;i++){
int op,x,y,k;
cin>>op>>x>>y;
if(op <= 2) cin>>k;
if(op == 1) tree.updateAdd(1,n,x,y,1,k);
if(op == 2) tree.updateMul(1,n,x,y,1,k);
if(op == 3) cout<<tree.query(1,n,x,y,1)<<'\n';
}
return 0;
}