块长开小就 WA,开大就 T,不知为何
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 5, B = 500;
ll n, m, a[N], fix[N], b[N][2], Mod;
inline int get(int x){
return (x - 1) / B + 1;
}
void push_down(int id){
for(int i = id * B; i < (id + 1) * B; ++i)
a[i] = (a[i] * b[id][0] + b[id][1]) % Mod;
b[id][0] = 1, b[id][1] = 0;
}
void update_add(int l, int r, int k){
k %= Mod;
if(get(l) == get(r)){
push_down(get(l));
for(int i = l; i <= r; ++i){
a[i] += k, fix[get(i)] += k;
a[i] %= Mod, fix[get(i)] %= Mod;
}
}else{
int i = l, j = r;
push_down(get(i));
while(get(i) == get(l)){
a[i] += k, fix[get(i)] += k;
a[i] %= Mod, fix[get(i)] %= Mod;
++i;
}
push_down(get(j));
while(get(j) == get(r)){
a[j] += k, fix[get(j)] += k;
a[j] %= Mod, fix[get(j)] %= Mod;
--j;
}
for(int p = get(i); p <= get(j); ++p){
b[p][0] += k, fix[p] += k * B;
b[p][0] %= Mod, fix[p] %= Mod;
}
}
}
void update_mul(int l, int r, int k){
k %= Mod;
if(get(l) == get(r)){
push_down(get(l));
for(int i = l; i <= r; ++i){
a[i] *= k, fix[get(i)] += (k - 1) * a[i];
a[i] %= Mod, fix[get(i)] %= Mod;
}
}else{
int i = l, j = r;
push_down(get(i));
while(get(i) == get(l)){
a[i] *= k, fix[get(i)] += (k - 1) * a[i];
a[i] %= Mod, fix[get(i)] %= Mod;
++i;
}
push_down(get(j));
while(get(j) == get(r)){
a[j] *= k, fix[get(j)] += (k - 1) * a[j];
a[j] %= Mod, fix[get(j)] %= Mod;
--j;
}
for(int p = get(i); p <= get(j); ++p){
b[p][1] *= k, fix[p] *= k;
b[p][1] %= Mod, fix[p] %= Mod;
}
}
}
int query(int l, int r){
ll ret = 0;
if(get(l) == get(r)){
for(int i = l; i <= r; ++i){
ret = (ret + a[i] * b[get(i)][0] + b[get(i)][1]) % Mod;
}
}else{
int i = l, j = r;
while(get(i) == get(l)){
ret = (ret + a[i] * b[get(i)][0] + b[get(i)][1]) % Mod;
++i;
}
while(get(j) == get(r)){
ret = (ret + a[j] * b[get(j)][0] + b[get(j)][1]) % Mod;
--j;
}
for(int p = get(i); p <= get(j); ++p){
ret = (ret + fix[p]) % Mod;
}
}
return ret;
}
int main(){
ios :: sync_with_stdio(0), cin.tie(0);
cin >> n >> Mod;
for(int i = 1; i <= n; ++i){
cin >> a[i];
a[i] %= Mod;
fix[get(i)] = (fix[get(i)] + a[i]) % Mod;
b[i][0] = 1;
}
cin >> m;
while(m--){
int op, l, r, k;
cin >> op;
if(op == 1){
cin >> l >> r >> k;
update_mul(l, r, k);
}else if(op == 2){
cin >> l >> r >> k;
update_add(l, r, k);
}else{
cin >> l >> r;
cout << query(l, r) % Mod << '\n';
}
}
return 0;
}