日常刷题2025-2-20
lz的序列问题
思路:常规线段树
比较常规的线段树。
代码
#include <bits/stdc++.h>
#define lson (rt << 1)
#define rson (rt << 1 | 1)using i64 = long long;const int mod = 1000000007;int a[200005];
struct node {i64 v, rmx, lz;
}tr[200005 << 2];i64 ksm(i64 a, i64 b) {i64 res = 1;while(b) {if (b & 1) {res = res * a % mod;}b >>= 1;a = a * a % mod;}return res;
}node mer(node x, node y) {if (x.v == 0) return y;node res = {0, 0, 0};res.v = x.rmx * y.v % mod + x.v;res.v %= mod;res.rmx = x.rmx * y.rmx % mod;return res;
}void push_down(int rt, int l, int r) {if (tr[rt].lz) {int mid = l + r >> 1;int x = tr[rt].lz;tr[lson].lz = x;tr[rson].lz = x;if (tr[rt].lz == 1) {tr[lson].v = mid - l + 1;tr[rson].v = r - mid;tr[lson].rmx = 1;tr[rson].rmx = 1;}else {tr[lson].v = (ksm(x, mid - l + 1) - 1) * x % mod * ksm(x - 1, mod - 2) % mod;tr[rson].v = (ksm(x, r - mid) - 1) * x % mod * ksm(x - 1, mod - 2) % mod;tr[lson].rmx = ksm(x, mid - l + 1);tr[rson].rmx = ksm(x, r - mid);}tr[rt].lz = 0;}
}void build(int rt, int l, int r) {if (l == r) {tr[rt].v = a[l];tr[rt].rmx = a[l]; return;}int mid = l + r >> 1;build(lson, l, mid);build(rson, mid + 1, r);tr[rt] = mer(tr[lson], tr[rson]);
}void update(int rt, int l, int r, int L, int R, int x) {if (l >= L && r <= R) {tr[rt].lz = x;if (x == 1) {tr[rt].v = r - l + 1;tr[rt].rmx = 1;}else {tr[rt].v = (ksm(x, r - l + 1) - 1) * x % mod * ksm(x - 1, mod - 2) % mod;tr[rt].rmx = ksm(x, (r - l + 1));}return;}push_down(rt, l, r);int mid = l + r >> 1;if (mid >= L)update(lson, l, mid, L, R, x);if (mid < R) {update(rson, mid + 1, r, L, R, x);}tr[rt] = mer(tr[lson], tr[rson]);
}node query(int rt, int l, int r, int L, int R) {if (l >= L && r <= R) {return tr[rt];}push_down(rt, l, r);node res = {0, 0, 0};int mid = l + r >> 1;if (mid >= L) {res = mer(res, query(lson, l, mid, L, R));}if (mid < R){res = mer(res, query(rson, mid + 1, r, L, R));}return res;
}void solve() {int n, m;std::cin >> n >> m;for (int i = 1; i <= n; i++) {std::cin >> a[i];}build(1, 1, n);while (m--) {int op;std::cin >> op;if (op == 1) {int l, r, x;std::cin >> l >> r >> x;update(1, 1, n, l, r, x);}else {int l, r;std::cin >> l >> r;std::cout << query(1, 1, n, l, r).v << '\n';}}
}signed main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int t = 1;// std::cin >> t;while (t--) {solve();}return 0;
}