1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <cstdio> using namespace std; using LL = long long; const int N = 100001; int n, p, m, op, l, r, d, w[N]; struct Node { int l, r, sum, mul, add; } tr[N << 2]; void eval(Node &t, LL mul, LL add) { t.sum = (t.sum * mul + (t.r - t.l + 1) * add) % p; t.mul = (t.mul * mul) % p; t.add = (t.add * mul + add) % p; } void pushup(int u) { tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % p; } void pushdown(int u) { if (tr[u].mul == 1 && tr[u].add == 0) return; eval(tr[u << 1], tr[u].mul, tr[u].add); eval(tr[u << 1 | 1], tr[u].mul, tr[u].add); tr[u].mul = 1, tr[u].add = 0; } void build(int u, int l, int r) { if (l == r) tr[u] = {l, r, w[l], 0, 0}; else { tr[u] = {l, r, 0, 1, 0}; int mid = l + r >> 1; build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); pushup(u); } } void update(int u, int l, int r, int mul, int add) { if (l <= tr[u].l && tr[u].r <= r) eval(tr[u], mul, add); else { pushdown(u); int mid = tr[u].l + tr[u].r >> 1; if (l <= mid) update(u << 1, l, r, mul, add); if (r > mid) update(u << 1 | 1, l, r, mul, add); pushup(u); } } int query(int u, int l, int r) { if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum; pushdown(u); int mid = tr[u].l + tr[u].r >> 1; int sum = 0; if (l <= mid) sum = query(u << 1, l, r); if (r > mid) sum = (sum + query(u << 1 | 1, l, r)) % p; return sum; } int main() { scanf("%d%d%d", &n, &m, &p); for (int i = 1; i <= n; ++i) scanf("%d", &w[i]); build(1, 1, n); while (m--) { scanf("%d%d%d", &op, &l, &r); if (op == 3) { printf("%d\n", query(1, l, r)); } else { scanf("%d", &d); if (op == 1) update(1, l, r, d, 0); else update(1, l, r, 1, d); } } return 0; }
|