C++ 实现区间浇水次数累加及查询:差分与前缀和优化详解
这道题是一个典型的**区间累加 + 区间查询**问题。虽然数据规模较小(n<100,q可能也较小),但我们可以用一种高效的方法来做:**差分数组 + 前缀和**。 下面我会详细讲解两种解法: 1. **朴素模拟法**(适用于本题小规模数据) 2. **差分 + 前缀和优化法**(适用于大规模数据,推荐掌握) --- ## 🧩 解法一:朴素模拟法(直接暴力) ### ✅ 思路 - 开一个数组 `a[1..n]`,初始全为0。 - 对每一轮浇水 `(L, R, x)`,用循环将 `a[L]` 到 `a[R]` 每个加上 `x`。 - 最后对区间 `[b, y]` 求和并输出。 ### ✅ C++ 代码实现 ```cpp #include <iostream> using namespace std; int main() { int n, q; cin >> n >> q; int a[105] = {0}; // 花浇水次数数组,下标从1开始 for (int i = 0; i < q; i++) { int L, R, x; cin >> L >> R >> x; for (int j = L; j <= R; j++) { a[j] += x; } } int b, y; cin >> b >> y; int sum = 0; for (int i = b; i <= y; i++) { sum += a[i]; } cout << sum << endl; return 0; } ``` ### ⏱ 复杂度分析 - 时间:O(q × 区间长度),最坏 O(q × n) - 空间:O(n) **适用于本题**(n < 100,数据量小)。 --- ## 🧩 解法二:差分 + 前缀和(推荐) 这种方法即使数据规模变大(比如 n=10⁵, q=10⁵),也能高效运行。 ### ✅ 原理 - **差分数组** `diff[i]`:记录相邻两朵花浇水次数的差值。 - 对区间 `[L, R]` 增加 `x`: `diff[L] += x` `diff[R+1] -= x` - 然后通过**前缀和**还原出每朵花的实际浇水次数: ``` a[i] = a[i-1] + diff[i] ``` - 最后对区间 `[b, y]` 求前缀和。 ### ✅ 步骤 1. 初始化 `diff` 数组全为0。 2. 对每一轮 `(L, R, x)`: - `diff[L] += x` - `diff[R+1] -= x` 3. 计算 `a[1..n]`: - `a[i] = a[i-1] + diff[i]` 4. 计算 `prefix[0..n]`: - `prefix[i] = prefix[i-1] + a[i]` 5. 输出 `prefix[y] - prefix[b-1]` ### ✅ C++ 代码实现 ```cpp #include <iostream> using namespace std; int main() { int n, q; cin >> n >> q; int diff[105] = {0}; // 差分数组,大小比n大1 for (int i = 0; i < q; i++) { int L, R, x; cin >> L >> R >> x; diff[L] += x; diff[R + 1] -= x; } int a[105] = {0}; // 每朵花的实际浇水次数 int prefix[105] = {0}; // 前缀和数组 for (int i = 1; i <= n; i++) { a[i] = a[i-1] + diff[i]; prefix[i] = prefix[i-1] + a[i]; } int b, y; cin >> b >> y; cout << prefix[y] - prefix[b-1] << endl; return 0; } ``` ### ⏱ 复杂度分析 - 时间:O(n + q) - 空间:O(n) **即使 n=1000万,q=1000万,也能轻松运行。** --- ## ✅ 两种方法对比 | 方法 | 时间复杂度 | 空间复杂度 | 适用场景 | |------|------------|------------|----------| | 朴素模拟 | O(q × 区间长度) | O(n) | 小规模数据(n,q<1000) | | 差分+前缀和 | O(n + q) | O(n) | 大规模数据(n,q可达10⁵+) | --- ## ⚠️ 常见陷阱与注意事项 1. **数组下标从1开始**:题目中花编号从1到n,建议数组下标也从1开始,避免混淆。 2. **差分数组边界**:`diff[R+1]` 容易越界,记得数组大小设为 `n+2`。 3. **前缀和查询公式**:`[b, y]` 的和 = `prefix[y] - prefix[b-1]`,不要忘记 `b-1`。 4. **数据类型**:如果浇水次数 x 很大(比如 x ≤ 10⁹),建议使用 `long long` 类型。 --- ## 📘 开发建议 - **优先掌握差分+前缀和**:这是处理区间多次修改+单次/多次查询的经典技巧。 - **输入输出加速**:如果数据量大,可加上: ```cpp ios::sync_with_stdio(false); cin.tie(nullptr); ``` - **代码模块化**:可以将差分更新、前缀和生成、区间查询封装成函数,提高可读性。 - **测试用例**:除了题目样例,建议测试边界情况,如: - 浇水区间覆盖全部花。 - 查询区间只有一朵花。 - b == y。 --- 如果你需要我帮你用 Python、Java 或其他语言实现,或者想要我讲解差分/前缀和的底层原理,欢迎继续提问! ######[AI写代码神器 | 1383点数解答 | 2026-06-06 21:28:22]
- Python实现:随机录入45位学生四次成绩函数大揭秘(GPT | 477点数解答 | 2024-12-17 17:00:35)382
- Python实现班级45位同学成绩生成、总评计算及分数统计(字节豆包 | 579点数解答 | 2024-12-21 11:55:01)272
- Python实现45位学生四次成绩随机录入及输出(GPT | 441点数解答 | 2024-12-21 21:02:22)276
- Python实战:45位同学成绩生成、总评计算与分数统计揭秘(字节豆包 | 688点数解答 | 2024-12-22 10:14:17)264
- 深度揭秘 Oracle Workarea Size Policy:参数调优助力数据库性能飞升(阿里通义 | 372点数解答 | 2024-05-13 10:54:45)271
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)410
- 补全含错误代码:Vue结合Element UI组件实现查询、新增及表格展示功能 ( | 400点数解答 | 2023-12-19 15:20:50)461
- 单线程频繁查ClickHouse致CPU飙升?这些优化方案速看!(DeepSeek | 491点数解答 | 2025-02-13 17:49:54)256
- MySQL:巧用 NOT LIKE 查询字段不包含特定字符串及注意要点 (DeepSeek | 264点数解答 | 2025-02-13 18:25:01)202
- 解析React 15与Vue 2:从O(n^3)到O(n),Diff算法时间复杂度计算及性能对比 (阿里通义 | 379点数解答 | 2023-11-09 01:49:19)369
- 缜密逻辑,全新无名杀“风餐”技能代码精心打造与深度解析 (字节豆包 | 469点数解答 | 2025-04-05 11:37:06)296
- 精准优化:明确需求,开启高效提升之旅! (字节豆包 | 52点数解答 | 2026-02-09 16:44:46)90