线段树
| |
| |
| template<class T, class F> |
| class SegmentTree { |
| const int n; |
| vector<T> node; |
| |
| void update(int rt, int l, int r, int pos, F f) { |
| if (r < pos || l > pos) return; |
| if (l == r) { |
| node[rt] = f(node[rt]); |
| return; |
| } |
| int mid = l + r >> 1; |
| update(rt << 1, l, mid, pos, f); |
| update(rt << 1 | 1, mid + 1, r, pos, f); |
| node[rt] = node[rt << 1] + node[rt << 1 | 1]; |
| } |
| |
| T query(int rt, int l, int r, int x, int y) { |
| if (l > y || r < x) return T::e(); |
| if (x <= l && r <= y) return node[rt]; |
| int mid = l + r >> 1; |
| return query(rt << 1, l, mid, x, y) + query(rt << 1 | 1, mid + 1, r, x, y); |
| } |
| |
| public: |
| SegmentTree(int _n):n(_n), node(_n << 2, T::e()) {} |
| SegmentTree(int _n, const vector<T> &src):n(_n), node(_n << 2, T::e()) { |
| function<void(int, int, int)> build = [&](int rt, int l, int r) { |
| if (l == r) { |
| node[rt] = src[l]; |
| return; |
| } |
| int mid = l + r >> 1; |
| build(rt << 1, l, mid); |
| build(rt << 1 | 1, mid + 1, r); |
| node[rt] = node[rt << 1] + node[rt << 1 | 1]; |
| }; |
| build(1, 1, n); |
| } |
| |
| void update(int pos, F f) { update(1, 1, n, pos, f); } |
| |
| T query(int x, int y) { return query(1, 1, n, x, y); } |
| }; |
| |
| |
| struct T { |
| int val; |
| static T e() { return T{ 0 }; } |
| friend T operator+(const T &a, const T &b) { return { a.val + b.val }; } |
| }; |
| |
| |
| struct F { |
| int diff; |
| T operator()(const T &x) { return T{ diff + x.val }; } |
| }; |
懒标记线段树
| |
| |
| template<class T, class F> |
| class SegmentTreeLazy { |
| const int n; |
| vector<T> node; |
| vector<F> lazy; |
| |
| void push_down(int rt) { |
| node[rt << 1] = lazy[rt](node[rt << 1]); |
| lazy[rt << 1] = lazy[rt](lazy[rt << 1]); |
| node[rt << 1 | 1] = lazy[rt](node[rt << 1 | 1]); |
| lazy[rt << 1 | 1] = lazy[rt](lazy[rt << 1 | 1]); |
| lazy[rt] = F::e(); |
| } |
| |
| void update(int rt, int l, int r, int x, int y, F f) { |
| if (l > y || r < x) return; |
| if (x <= l && r <= y) { |
| node[rt] = f(node[rt]); |
| lazy[rt] = f(lazy[rt]); |
| return; |
| } |
| push_down(rt); |
| int mid = l + r >> 1; |
| update(rt << 1, l, mid, x, y, f); |
| update(rt << 1 | 1, mid + 1, r, x, y, f); |
| node[rt] = node[rt << 1] + node[rt << 1 | 1]; |
| } |
| |
| T query(int rt, int l, int r, int x, int y) { |
| if (l > y || r < x) return T::e(); |
| if (x <= l && r <= y) return node[rt]; |
| push_down(rt); |
| int mid = l + r >> 1; |
| return query(rt << 1, l, mid, x, y) + query(rt << 1 | 1, mid + 1, r, x, y); |
| } |
| |
| public: |
| SegmentTreeLazy(int _n):n(_n), node(_n << 2, T::e()), lazy(_n << 2, F::e()) {} |
| SegmentTreeLazy(int _n, const vector<T> &src):n(_n), node(_n << 2, T::e()), lazy(_n << 2, F::e()) { |
| function<void(int, int, int)> build = [&](int rt, int l, int r) { |
| if (l == r) { |
| node[rt] = src[l]; |
| return; |
| } |
| int mid = l + r >> 1; |
| build(rt << 1, l, mid); |
| build(rt << 1 | 1, mid + 1, r); |
| node[rt] = node[rt << 1] + node[rt << 1 | 1]; |
| }; |
| build(1, 1, n); |
| } |
| |
| void update(int x, int y, F f) { |
| update(1, 1, n, x, y, f); |
| } |
| |
| T query(int x, int y) { |
| return query(1, 1, n, x, y); |
| } |
| }; |
| |
| int p; |
| |
| struct T { |
| ll val; |
| int len; |
| static T e() { return T{ 0,0 }; } |
| friend T operator+(const T &a, const T &b) { return T{ (a.val + b.val) % p,a.len + b.len }; } |
| }; |
| |
| |
| struct F { |
| ll sum; |
| ll mul; |
| static F e() { return F{ 0,1 }; } |
| T operator()(T x) { return T{ (mul * x.val % p + sum * x.len % p) % p,x.len }; } |
| F operator()(F g) { return F{ (mul * g.sum % p + sum) % p,mul * g.mul % p }; } |
| }; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧