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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| #include <bits/stdc++.h> using namespace std; using namespace std;
const int MAXN = 100010; long long n, m, p; long long input[MAXN]; struct node { long long l,r; long long sum,mlz,plz; }tree[MAXN<<2]; inline void build(long long i, long long l, long long r) { tree[i].l = l; tree[i].r = r; tree[i].mlz = 1; if(l ==r ) {tree[i].sum = input[l]%p; return;} long long mid = (l+r)>>1; build(i<<1, l, mid); build(i<<1|1, mid+1, r); tree[i].sum = (tree[i<<1].sum+tree[i<<1|1].sum)%p; return; } inline void pushdown(long long i) { long long k1 = tree[i].mlz,k2=tree[i].plz; tree[i<<1].sum = (tree[i<<1].sum*k1+k2*(tree[i<<1].r-tree[i<<1].l+1))%p; tree[i<<1|1].sum = (tree[i<<1|1].sum*k1+k2*(tree[i<<1|1].r-tree[i<<1|1].l+1))%p; tree[i<<1].mlz = (tree[i<<1].mlz*k1)%p; tree[i<<1|1].mlz = (tree[i<<1|1].mlz*k1)%p; tree[i<<1].plz = (tree[i<<1].plz*k1+k2)%p; tree[i<<1|1].plz = (tree[i<<1|1].plz*k1+k2)%p; tree[i].plz = 0; tree[i].mlz = 1; return ; } inline void mul(long long i, long long l, long long r, long long k) { if(tree[i].r<l || tree[i].l>r) return ; if(tree[i].l >= l && tree[i].r<=r) { tree[i].sum = (tree[i].sum*k)%p; tree[i].mlz = (tree[i].mlz*k)%p; tree[i].plz = (tree[i].plz*k)%p; return ; } pushdown(i); if(tree[i<<1].r >= l) mul(i<<1, l, r, k); if(tree[i<<1|1].l <= r) mul(i<<1|1, l, r, k); tree[i].sum = (tree[i<<1].sum+tree[i<<1|1].sum)%p; return; } inline void add(long long i, long long l, long long r, long long k) { if(tree[i].r<l || tree[i].l>r) return; if(tree[i].l>=l && tree[i].r<=r){ tree[i].sum += ((tree[i].r-tree[i].l+1)*k)%p; tree[i].plz = (tree[i].plz+k)%p; return; } pushdown(i); if(tree[i<<1].r >= l) add(i<<1, l, r, k); if(tree[i<<1|1].l <= r) add(i<<1|1, l, r, k); tree[i].sum = (tree[i<<1].sum+tree[i<<1|1].sum)%p; return; } inline long long search(long long i, long long l, long long r) { if(tree[i].r<l || tree[i].l>r) return 0; if(tree[i].l>=l && tree[i].r<=r) return tree[i].sum; pushdown(i); long long sum = 0; if(tree[i<<1].r >= l) sum+=search(i<<1, l, r)%p; if(tree[i<<1|1].l <= r) sum+=search(i<<1|1, l, r)%p; return sum%p; } int main(void) { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m >> p; for (long long i = 1; i <= n; ++i) cin >> input[i]; build(1, 1, n);
for (int i = 1; i <= m; ++i) { long long op, l, r, v; cin >> op; if(op == 1) { cin >> l >> r >> v; v %= p; mul(1, l, r, v); } else if(op == 2) { cin >> l >> r >> v; v %= p; add(1, l, r, v); } else if (op == 3) { cin >> l >> r; cout << search(1, l, r) << '\n'; } } return 0; }
|