RT,分块暴力,2、9、10点一直会超时,加上快读反而更慢,不知道是我快读写假了还是咋的。。。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
const int N = 1e5 + 5;
int n, m, p, block, id[N];
ll a[N], s[N], add[N], mul[N];
void push_down(int k) {
for (int i = (k - 1) * block + 1; i <= k * block; ++i)
a[i] = (a[i] * mul[k] + add[k] + p) % p;
mul[k] = 1, add[k] = 0;
return ;
}
void modify_add(int l, int r, int c) {
int ld = id[l], rd = id[r];
push_down(ld);
if (ld == rd) {
for (int i = l; i <= r; ++i) {
a[i] = (a[i] + c + p) % p;
s[ld] = (s[ld] + c + p) % p;
}
return ;
}
push_down(rd);
for (int i = l; id[i] == ld; ++i) {
a[i] = (a[i] + c + p) % p;
s[ld] = (s[ld] + c + p) % p;
}
for (int i = ld + 1; i < rd; ++i) {
add[i] = (add[i] + c + p) % p;
s[i] = (s[i] + c * block + p) % p;
}
for (int i = r; id[i] == rd; --i) {
a[i] = (a[i] + c + p) % p;
s[rd] = (s[rd] + c + p) % p;
}
return ;
}
void modify_mul(int l, int r, int c) {
int ld = id[l], rd = id[r];
push_down(ld);
if (ld == rd) {
for (int i = l; i <= r; ++i) {
s[ld] = (s[ld] + a[i] * (c - 1) + p) % p;
a[i] = (a[i] * c + p) % p;
}
return ;
}
push_down(rd);
for (int i = l; id[i] == ld; ++i) {
s[ld] = (s[ld] + a[i] * (c - 1) + p) % p;
a[i] = (a[i] * c + p) % p;
}
for (int i = ld + 1; i < rd; ++i) {
mul[i] = (mul[i] * c + p) % p;
s[i] = (s[i] * c + p) % p;
add[i] = (add[i] + p) * c % p;
}
for (int i = r; id[i] == rd; --i) {
s[rd] = (s[rd] + a[i] * (c - 1) + p) % p;
a[i] = (a[i] * c + p) % p;
}
return ;
}
ll query(int l, int r) {
int ld = id[l], rd = id[r];
ll ans = 0;
if (ld == rd) {
for (int i = l; i <= r; ++i)
ans = (ans + a[i] * mul[ld] + add[ld] + p) % p;
return ans;
}
for (int i = l; id[i] == ld; ++i)
ans = (ans + a[i] * mul[ld] + add[ld] + p) % p;
for (int i = ld + 1; i < rd; ++i)
ans = (ans + s[i] + p) % p;
for (int i = r; id[i] == rd; --i)
ans = (ans + a[i] * mul[rd] + add[rd] + p) % p;
return ans;
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> m >> p;
block = sqrt(n);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
id[i] = (i - 1) / block + 1;
s[id[i]] += a[i];
mul[i] = 1;
}
for (int i = 1; i <= m; ++i) {
int opt, x, y, k;
cin >> opt;
if (opt == 1) {
cin >> x >> y >> k;
modify_mul(x, y, k);
}
else if (opt == 2) {
cin >> x >> y >> k;
modify_add(x, y, k);
}
else {
cin >> x >> y;
cout << query(x, y) << '\n';
}
}
return 0;
}