2 条题解
-
2XzyStudio (admin) LV 8 MOD 机房蒟蒻 tayz @ 2024-03-17 11:13:12
根据9Cirno的题解重写一个Python实现的
SegmentTree
类class SegmentTree: tree = dict() lazy = dict() a = None def __init__(self, a): self.a = a def ls(self, p): return p << 1 def rs(self, p): return p << 1 | 1 def push_up(self, p): self.tree[p] = self.tree[self.ls(p)] + self.tree[self.rs(p)] def build(self, p, l, r): if l == r: self.tree[p] = self.a[l] return m = (l + r) >> 1 self.build(self.ls(p), l, m) self.build(self.rs(p), m + 1, r) self.push_up(p) def add_lazy(self, p, l, r, k): self.tree[p] += k * (r - l + 1) if self.lazy.get(p, 0) == 0: self.lazy[p] = k else: self.lazy[p] += k def push_down(self, p, l, r): if self.lazy.get(p, 0) == 0: return m = (l + r) >> 1 self.add_lazy(self.ls(p), l, m, self.lazy[p]) self.add_lazy(self.rs(p), m + 1, r, self.lazy[p]) self.lazy[p] = 0 def update(self, L, R, p, l, r, k): if L <= l and r <= R: self.add_lazy(p, l, r, k) return self.push_down(p, l, r) m = (l + r) >> 1 if L <= m: self.update(L, R, self.ls(p), l, m, k) if R > m: self.update(L, R, self.rs(p), m + 1, r, k) self.push_up(p) def query(self, L, R, p, l, r): if L <= l and r <= R: return self.tree[p] self.push_down(p, l, r) m = (l + r) >> 1 res = 0 if L <= m: res += self.query(L, R, self.ls(p), l, m) if R > m: res += self.query(L, R, self.rs(p), m + 1, r) return res if __name__ == "__main__": n, m = map(int, input().strip().split()) a = list(map(int, input().strip().split())) a.insert(0, 0) # 不使用0号位 st = SegmentTree(a) st.build(1, 1, n) for _ in range(m): ipt = input().strip().split() if len(ipt) == 4: x, y, k = map(int, ipt[1:]) st.update(x, y, 1, 1, n, k) else: x, y = map(int, ipt[1:]) ans = st.query(x, y, 1, 1, n) print(ans, (ans << 1) + (ans << 2))
如果需要实现其他的维护,您需要自定义类继承
SegmentTree
类,并重写add_lazy
方法 -
22024-03-13 20:21:06@
省流:线段树板子
#include <iostream> using namespace std; typedef long long ll; const int N = 100010; struct segment_tree { private: void add(ll k) { laz += k; sum += k * (r - l + 1); } void push_down() { if (laz) { ls->add(laz); rs->add(laz); laz = 0; } } public: ll l, r; ll sum, laz; segment_tree *ls, *rs; void push_up() { sum = ls->sum + rs->sum; } void update(int L, int R, int k) { if (L <= l && R >= r) { add(k); return; } push_down(); if (L <= ls->r) ls->update(L, R, k); if (R >= rs->l) rs->update(L, R, k); push_up(); } ll query(ll L, ll R) { if (L <= l && R >= r) return sum; push_down(); ll res = 0; if (L <= ls->r) res += ls->query(L, R); if (R >= rs->l) res += rs->query(L, R); return res; } } tree[N << 2], *pos = tree; ll a[N]; segment_tree *build(ll l, ll r) { auto tmp = pos++; tmp->l = l, tmp->r = r; if (l != r) { ll mid = (l + r) >> 1; tmp->ls = build(l, mid); tmp->rs = build(mid + 1, r); tmp->push_up(); } else tmp->sum = a[l]; return tmp; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; auto rt = build(1, n); while (m--) { int op, l, r, k; cin >> op; if (op == 1) { cin >> l >> r >> k; rt->update(l, r, k); } else { cin >> l >> r; ll ans = rt->query(l, r); cout << ans << ' ' << (ans << 1) + (ans << 2) << '\n'; } } return 0; }
- 1