线段树板子求调

P3373 【模板】线段树 2

改了一下 ```cpp #include <bits/stdc++.h> #define ll long long using namespace std; ll a[100001], add[400001], mul[400001], tree[400001]; ll n, q, mod; void pushup(ll p) { tree[p] = (tree[p << 1] + tree[p << 1 | 1]) % mod; } void pushdown(ll p, ll l, ll r) { ll lc = (p << 1), rc = ((p << 1) | 1), mid = l + ((r - l) >> 1); if (mul[p] != 1) { mul[lc] *= mul[p], mul[rc] *= mul[p]; mul[lc] %= mod, mul[rc] %= mod; add[lc] *= mul[p], add[rc] *= mul[p]; add[lc] %= mod, add[rc] %= mod; tree[lc] *= mul[p], tree[rc] *= mul[p]; tree[lc] %= mod, tree[rc] %= mod; mul[p] = 1; } if (add[p]) { tree[lc] += add[p] * (mid - l + 1), tree[rc] += add[p] * (r - mid); tree[lc] %= mod, tree[rc] %= mod; add[lc] += add[p], add[rc] += add[p]; add[lc] %= mod, add[rc] %= mod; add[p] = 0; } return ; } void build(ll L, ll R, ll p) { mul[p] = 1; if (L == R) { tree[p] = a[L]; return ; } ll mid = L + ((R - L) >> 1); build(L, mid, (p << 1)); build(mid + 1, R, ((p << 1) | 1)); pushup(p); return ; } void addsum(ll L, ll R, ll l, ll r, ll p, ll k) { ll mid = l + ((r - l) >> 1); if (L <= l && r <= R) { tree[p] += k * (r - l + 1), add[p] += k; tree[p] %= mod, add[p] %= mod; return ; } pushdown(p, l, r); if (L <= mid) addsum(L, R, l, mid, (p << 1), k); if (mid + 1 <= R) addsum(L, R, mid + 1, r, ((p << 1) | 1), k); return ; } void times(ll L, ll R, ll l, ll r, ll p, ll k) { ll mid = l + ((r - l) >> 1); if (L <= l && r <= R) { tree[p] *= k, add[p] *= k, mul[p] *= k; tree[p] %= mod, add[p] %= mod, mul[p] %= mod; return ; } pushdown(p, l, r); if (L <= mid) times(L, R, l, mid, (p << 1), k); if (mid + 1 <= R) times(L, R, mid + 1, r, ((p << 1) | 1), k); return ; } ll getans(ll L, ll R, ll l, ll r, ll p) { ll mid = l + ((r - l) >> 1), tot = 0; if (L <= l && r <= R) return tree[p]; pushdown(p, l, r); if (L <= mid) tot += getans(L, R, l, mid, (p << 1)); tot %= mod; if (mid + 1 <= R) tot += getans(L, R, mid + 1, r, ((p << 1) | 1)); return tot % mod; } int main() { cin >> n >> q >> mod; for (int i = 1; i <= n; i++) cin >> a[i]; build(1, n, 1); for (int i = 1; i <= q; i++) { int op, x, y, k; cin >> op; if (op == 1) { cin >> x >> y >> k; times(x, y, 1, n, 1, k); } else if (op == 2) { cin >> x >> y >> k; addsum(x, y, 1, n, 1, k); } else { cin >> x >> y; cout << getans(x, y, 1, n, 1) << endl; } } return 0; } /* 5 5 38 1 5 4 2 3 2 1 4 1 3 2 5 1 2 4 2 2 3 5 5 3 1 4 */ ``` 输入是能输进去了,但是样例过不去
by 紪絽 @ 2023-10-17 21:17:21


|