动态开点,全wa
#include <iostream>
#include <cstdio>
#include <cctype>
#define ll long long
using namespace std;
const int N = 1e5+1;
ll ls[2*N], rs[2*N], a[2*N];
ll n, q, m;
ll tot, root = 1;
struct node
{
ll val, mul, add;
}d[2*N];
inline ll read() {
ll x = 0, w = 1;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-')w = -1;
ch = getchar();
}
while(isdigit(ch)) {
x = x * 10 + (ch-'0');
ch = getchar();
}
return x * w;
}
inline void build(ll s, ll t, ll& p) {
if(!p)p = ++tot;
d[p].add = 0;
d[p].mul = 1;
if(s == t) {
d[p].val = a[s] % m;
return ;
}
ll mid = s + ((t - s) >> 1);
build(s, mid, ls[p]);
build(mid + 1, t, rs[p]);
d[p].val = d[ls[p]].val + d[rs[p]].val;
d[p].val %= m;
}
inline void pushdown(ll s, ll t, ll& p) {
ll mid = s + ((t - s) >> 1);
d[ls[p]].val = (d[ls[p]].val * d[p].mul + d[p].add * (m - s + 1)) % m;
d[rs[p]].val = (d[rs[p]].val * d[p].mul + d[p].add * (t - m)) % m;
d[ls[p]].mul *= d[p].mul;
d[rs[p]].mul *= d[p].mul;
d[ls[p]].add += d[ls[p]].add * d[p].mul;
d[rs[p]].add += d[rs[p]].add * d[p].mul;
d[ls[p]].mul %= m;
d[rs[p]].mul %= m;
d[ls[p]].add %= m;
d[rs[p]].add %= m;
d[p].mul = 1;
d[p].add = 0;
}
inline void update_mul(ll l, ll r, ll k, ll s, ll t, ll& p) {
if(!p) p = ++tot;
if(l > t || r < s) return ;
if(l >= s && r <= t) {
d[p].val = (d[p].val * k) % m;
d[p].add = (d[p].add * k) % m;
d[p].mul = (d[p].mul * k) % m;
return ;
}
ll mid = s + ((t - s) >> 1);
pushdown(s, t, p);
update_mul(l, r, k, s, mid, ls[p]);
update_mul(l, r, k, mid + 1, t, rs[p]);
d[p].val = (d[ls[p]].val + d[rs[p]].val) % m;
}
inline void update_add(ll l, ll r, ll k, ll s, ll t, ll& p) {
if(!p) p = ++tot;
if(l > t || r < s) return ;
if(l <= s && r >= t) {
d[p].val = (d[p].val + k*(t - s + 1)) % m;
d[p].add = (d[p].add + k) % m;
return ;
}
ll mid = s + ((t - s) >> 1);
pushdown(s, t, p);
update_add(l, r, l, s, mid, ls[p]);
update_add(l, r, k, mid + 1, t, rs[p]);
d[p].val = (d[ls[p]].val + d[rs[p]].val) % m;
}
inline ll getsum(ll l, ll r, ll s, ll t, ll& p) {
if(l > t || r < s) return 0;
if(l <= s && r >= t) {
return d[p].val;
}
ll mid = s + ((t - s) >> 1);
pushdown(s, t, p);
ll sum = 0;
sum += getsum(l, r, s, mid, ls[p]) % m;
sum += getsum(l, r, mid + 1, t, rs[p]) % m;
return sum % m;
}
int main(){
ios::sync_with_stdio(false);
n = read(), q = read(), m = read();
for(int i = 1; i <= n; i++) {
a[i] = read();
}
build(1ll, n, root);
for(int i = 1; i <= q; i++) {
ll num = read(), x = read(), y = read();
if(num == 1) {//乘 k
ll k = read();
update_mul(x, y, k, 1ll, n, root);
}
else if(num == 2) {
ll k = read();
update_add(x, y, k, 1ll, n, root);
}
else {
ll res = getsum(x, y, 1ll, n, root);
cout << res << endl;
}
}
return 0;
}