懒惰有时候是进步的源动力

懒惰有时候是进步的源动力.


vim的颜色主题有好几百个,除非自己有耐心慢慢调教出一个自己完全满意的配色方案,
否则在这几百个里找出一个合适的也是一件痛苦的事情.
好在有比我更懒的人,弄了一个网页预览所有vim配色主题的工具:vimcolorschemetest
http://code.google.com/p/vimcolorschemetest/

几百个主题一起对比显示,有点壮观吧,这么多有可能看花了眼,所以只能慢慢选了,这个可再没办法偷懒了.
有点奇怪的是,有的配色主题显示的较早的版本,而不是最新的,大概是缓存的吧.

懒惰标记(Lazy Propagation)是线段树中一种优化技术,用于**延迟更新操作**,以避免对线段树中不必要的节点进行重复计算。当线段树需要处理**区间更新**(如区间加法、区间赋值等)时,频繁地更新所有相关的叶子节点会导致效率低下。此时,懒惰标记就能通过“暂时记录更新操作,等到真正需要时才执行”的方式,显著提升性能。 --- ### 懒惰标记的原理: 1. **引入懒惰数组**:我们维护一个 `lazy[]` 数组,用来记录每个节点“待执行的更新操作”。 2. **更新操作延迟执行**: - 当对一个区间进行更新时,如果当前节点对应的区间完全包含在目标区间内,则将更新操作记录在当前节点的 `lazy` 值中,而不是立即下传到子节点。 - 在后续查询或更新操作访问子节点之前,再将 `lazy` 标记下传,执行实际的更新。 3. **标记下传函数**:在访问子节点前,必须将当前节点的 `lazy` 标记应用到子节点,并清空当前节点的 `lazy`。 --- ### 示例:使用懒惰标记实现区间加法更新 下面是一个使用懒惰标记的线段树实现,支持以下操作: - 区间加法更新(将某个区间的所有元素加上一个值) - 区间求和查询 ```cpp #include <bits/stdc++.h> using namespace std; #define MAXN 100005 long long tree[MAXN * 4]; long long lazy[MAXN * 4]; void push(int node, int left, int right) { if (lazy[node] != 0) { // 将延迟操作下传给子节点 tree[node] += (long long)(right - left + 1) * lazy[node]; if (left != right) { lazy[node * 2] += lazy[node]; lazy[node * 2 + 1] += lazy[node]; } lazy[node] = 0; // 清空当前节点的懒惰标记 } } void build(int node, int left, int right, int *arr) { if (left == right) { tree[node] = arr[left]; } else { int mid = (left + right) / 2; build(node * 2, left, mid, arr); build(node * 2 + 1, mid + 1, right, arr); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } } void update_range(int node, int left, int right, int ul, int ur, long long val) { push(node, left, right); // 先检查并处理懒惰标记 if (ur < left || ul > right) return; if (ul <= left && right <= ur) { lazy[node] += val; push(node, left, right); // 再次更新当前节点 return; } int mid = (left + right) / 2; update_range(node * 2, left, mid, ul, ur, val); update_range(node * 2 + 1, mid + 1, right, ul, ur, val); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } long long query(int node, int left, int right, int ql, int qr) { push(node, left, right); if (qr < left || ql > right) return 0; if (ql <= left && right <= qr) return tree[node]; int mid = (left + right) / 2; return query(node * 2, left, mid, ql, qr) + query(node * 2 + 1, mid + 1, right, ql, qr); } int main() { int n; cin >> n; int *arr = new int[n + 1]; for (int i = 1; i <= n; ++i) cin >> arr[i]; build(1, 1, n, arr); int m; cin >> m; while (m--) { int op; cin >> op; if (op == 0) { int l, r; long long val; cin >> l >> r >> val; update_range(1, 1, n, l, r, val); } else { int l, r; cin >> l >> r; cout << query(1, 1, n, l, r) << endl; } } delete[] arr; return 0; } ``` --- ### 代码解释: - `push()` 函数:检查当前节点是否有懒惰标记,如果有则下传到子节点,并更新当前节点的值。 - `build()`:递归构建线段树。 - `update_range()`:实现区间加法更新,结合懒惰标记减少不必要的子节点更新。 - `query()`:查询区间和,同时处理懒惰标记。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值