← 目录 / 第十一章 · STL 标准模板库 / 11.13.4 数值运算

11.13.4 数值运算

accumulate、partial_sum、iota —— 来自 <numeric> 头文件的数值类算法,求和、前缀和、批量赋值。

📂 引入头文件:#include <numeric> —— 求和、累加等数值算法都在这里(不是 <algorithm>)。
本页目录
① accumulate —— 求和

把区间内所有元素累加起来。第三个参数是初始值,同时也决定了返回值的类型。

C++ · accumulate 求和
1vector<int> v = {1, 2, 3, 4, 5};
2int sum = accumulate(v.begin(), v.end(), 0);
3cout << "求和: " << sum << endl; // 求和: 15
4
5// 第三个参数是初始值,也是返回值的类型
6long long big_sum = accumulate(v.begin(), v.end(), 0LL);
⚠️
小技巧:对于大数求和,初始值写 0LL 而不是 0,否则结果可能溢出 int。这是因为 accumulate 的返回类型是根据初始值的类型推导的——写 0 就是按 int 一路累加(容易溢出),写 0LL 就是按 long long 累加。
② partial_sum —— 前缀和

计算前缀和数组:结果数组的第 i 个元素,等于原数组前 i+1 个元素的总和。竞赛中常用前缀和快速计算"任意区间的和"。

v = {1, 2, 3, 4, 5} → 前缀和 pre
原数组 v
1
2
3
4
5
前缀和 pre(每一格是前面所有格子的累计总和)
1
3
6
10
15
pre[2] = 6 表示 v[0] + v[1] + v[2] = 1 + 2 + 3 = 6。有了前缀和数组,想知道"原数组某一段区间的和"就不用每次重新累加,直接用两个前缀和相减即可(O(1) 查询)。
C++ · partial_sum 计算前缀和
1vector<int> v = {1, 2, 3, 4, 5};
2vector<int> pre(v.size());
3partial_sum(v.begin(), v.end(), pre.begin());
4// pre 变成 {1, 3, 6, 10, 15}
③ iota —— 递增赋值

把区间内的元素依次填充成从某个起始值开始、每次加 1 的连续整数。常用于快速生成"下标数组"(比如配合 sort 间接排序时用到的索引序列)。

C++ · iota 生成连续整数
1vector<int> v(5);
2iota(v.begin(), v.end(), 1);
3// v 变成 {1, 2, 3, 4, 5}
4
5iota(v.begin(), v.end(), 10);
6// v 变成 {10, 11, 12, 13, 14}
📌
典型用法——间接排序:想按某个数组的值排序,但又想知道排序后每个值原本的下标,可以先用 iota 生成 {0, 1, 2, ...} 的下标数组,再用自定义比较函数对下标数组 sort,排序依据是 v[下标] 的大小。这样原数组不被破坏,还能拿到排序后的下标顺序。