C++ STL算法函数详解

STL(Standard Template Library)中的算法函数是ACM竞赛中的利器,掌握它们可以大幅提高编码效率和程序性能。本文将详细介绍常用算法函数的使用方法、复杂度分析及实战应用。

目录

排序相关算法

sort

// 对[first, last)范围内的元素进行排序
sort(first, last);
sort(first, last, comp);  // 使用自定义比较函数
  • 时间复杂度: O(n log n) - 基于快速排序、堆排序和插入排序的混合优化算法
  • 空间复杂度: O(log n) - 用于递归调用栈

使用示例:

vector<int> v = {5, 2, 8, 3, 1, 7};
sort(v.begin(), v.end());  // 升序排序: 1, 2, 3, 5, 7, 8
sort(v.begin(), v.end(), greater<int>());  // 降序排序: 8, 7, 5, 3, 2, 1

// 自定义比较函数
struct Point { int x, y; };
vector<Point> points = { {3, 4}, {1, 2}, {3, 2} };
sort(points.begin(), points.end(), [](const Point& a, const Point& b) {
    if (a.x == b.x) return a.y < b.y;
    return a.x < b.x;
});  // 先按x排序,x相同则按y排序

ACM应用场景:

  • 贪心算法的预处理
  • 区间问题的预排序
  • 用于优化搜索范围

易错点:

  • 自定义比较函数必须满足严格弱序关系(否则会产生未定义行为)
  • 使用自定义比较时,要确保相等情况返回false

stable_sort

// 稳定排序,保持相等元素的相对顺序
stable_sort(first, last);
stable_sort(first, last, comp);
  • 时间复杂度: 如果有足够内存为O(n log n),否则为O(n log² n)
  • 空间复杂度: 如果有足够内存为O(n),否则为O(1)

使用示例:

struct Student {
    string name;
    int score;
};
vector<Student> students = { {"Alice", 85}, {"Bob", 90}, {"Charlie", 85} };
stable_sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
    return a.score > b.score;  // 按分数降序,相同分数保持原顺序
});
// 结果: [{"Bob", 90}, {"Alice", 85}, {"Charlie", 85}]

partial_sort

// 将范围[first, middle)中的元素按顺序排列,剩余元素无序
partial_sort(first, middle, last);
partial_sort(first, middle, last, comp);
  • 时间复杂度: O(n log m),其中n=(last-first),m=(middle-first)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {5, 2, 8, 3, 1, 7, 4};
// 只排序前3个元素
partial_sort(v.begin(), v.begin() + 3, v.end());
// 结果: [1, 2, 3, ?, ?, ?, ?] (其中?为原数组中的其他元素,顺序不确定)

ACM应用场景:

  • 【TopK问题】- 只需要找出最大/最小的K个元素

nth_element

// 重排[first, last),使得nth位置的元素是排序后应该在那个位置的元素
// 且保证nth之前的元素都不大于它,nth之后的元素都不小于它
nth_element(first, nth, last);
nth_element(first, nth, last, comp);
  • 时间复杂度: O(n) 平均情况
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {5, 2, 8, 3, 1, 7, 4};
// 找到中位数(第4个元素)
nth_element(v.begin(), v.begin() + 3, v.end());
int median = v[3];  // 现在v[3]就是中位数

ACM应用场景:

  • 【快速查找】第K大/小的元素
  • 【分治算法】在分区后找到划分点

查找相关算法

binary_search

// 检查[first, last)中是否存在等于value的元素
bool exists = binary_search(first, last, value);
bool exists = binary_search(first, last, value, comp);
  • 时间复杂度: O(log n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 5, 7, 8};  // 必须是有序集合
bool found = binary_search(v.begin(), v.end(), 5);  // true
found = binary_search(v.begin(), v.end(), 4);  // false

ACM应用场景:

  • 【二分查找】判断元素是否存在
  • 【离散化】后的查询

易错点:

  • 【必须对有序数组使用】,否则结果未定义

lower_bound / upper_bound

// lower_bound: 返回指向>=value的第一个元素的迭代器
auto it = lower_bound(first, last, value);
auto it = lower_bound(first, last, value, comp);

// upper_bound: 返回指向>value的第一个元素的迭代器
auto it = upper_bound(first, last, value);
auto it = upper_bound(first, last, value, comp);
  • 时间复杂度: O(log n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 3, 3, 5, 8};  // 有序数组
auto it1 = lower_bound(v.begin(), v.end(), 3);  // 指向第一个3
auto it2 = upper_bound(v.begin(), v.end(), 3);  // 指向5
int count = it2 - it1;  // 值为3的元素个数(3个)

// 求小于等于4的最大值
auto it3 = upper_bound(v.begin(), v.end(), 4);
int result = *(it3 - 1);  // 结果为3

// 求大于等于4的最小值
auto it4 = lower_bound(v.begin(), v.end(), 4);
int result2 = *it4;  // 结果为5

ACM应用场景:

  • 【二分答案】的实现
  • 【离散化】操作
  • 【区间查询】问题
  • 【计数排序】代替map

易错点:

  • 返回迭代器可能指向end(),使用前需要检查
  • 必须对有序容器使用

find / find_if

// 查找等于value的第一个元素
auto it = find(first, last, value);

// 查找满足谓词的第一个元素
auto it = find_if(first, last, pred);

// 查找不满足谓词的第一个元素
auto it = find_if_not(first, last, pred);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 3, 5, 7, 9};
auto it = find(v.begin(), v.end(), 5);  // 指向5
auto it2 = find_if(v.begin(), v.end(), [](int x) { return x > 6; });  // 指向7

ACM应用场景:

  • 无序数据中的元素查找
  • 条件性搜索

数值操作算法

accumulate

// 计算[first, last)中所有元素的总和,init为初始值
T sum = accumulate(first, last, init);
T sum = accumulate(first, last, init, op);  // 使用自定义操作
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 4, 5};
int sum = accumulate(v.begin(), v.end(), 0);  // 15
int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());  // 120

// 字符串连接
vector<string> sv = {"Hello", " ", "World"};
string result = accumulate(sv.begin(), sv.end(), string(""));  // "Hello World"

// 自定义结构
vector<pair<int, int>> points = { {1, 2}, {3, 4}, {5, 6} };
int sum_x = accumulate(points.begin(), points.end(), 0, 
                       [](int sum, const pair<int, int>& p) { return sum + p.first; });  // 9

ACM应用场景:

  • 【求和】操作
  • 【乘积】计算
  • 通过自定义函数实现【复杂累积】操作

partial_sum

// 计算前缀和并存储到result
partial_sum(first, last, result);
partial_sum(first, last, result, op);  // 使用自定义操作
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 4, 5};
vector<int> prefix_sum(v.size());
partial_sum(v.begin(), v.end(), prefix_sum.begin());
// prefix_sum: [1, 3, 6, 10, 15]

// 前缀乘积
vector<int> prefix_product(v.size());
partial_sum(v.begin(), v.end(), prefix_product.begin(), multiplies<int>());
// prefix_product: [1, 2, 6, 24, 120]

ACM应用场景:

  • 【前缀和】计算
  • 【动态规划】中的状态转移

adjacent_difference

// 计算相邻元素差并存储到result
adjacent_difference(first, last, result);
adjacent_difference(first, last, result, op);  // 使用自定义操作
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 3, 6, 10, 15};
vector<int> diff(v.size());
adjacent_difference(v.begin(), v.end(), diff.begin());
// diff: [1, 2, 3, 4, 5]

// 计算比值
vector<double> ratio(v.size());
adjacent_difference(v.begin(), v.end(), ratio.begin(), [](int a, int b) { 
    return a / (double)b; 
});

ACM应用场景:

  • 【差分数组】构造
  • 【变化率】计算

inner_product

// 计算两个序列的内积,init为初始值
T result = inner_product(first1, last1, first2, init);
T result = inner_product(first1, last1, first2, init, op1, op2);  // 自定义操作
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v1 = {1, 2, 3};
vector<int> v2 = {4, 5, 6};
// (1*4 + 2*5 + 3*6) + 0 = 32
int dot_product = inner_product(v1.begin(), v1.end(), v2.begin(), 0);

// 计算向量距离的平方
vector<int> p1 = {1, 2, 3};
vector<int> p2 = {4, 5, 6};
int distance_sq = inner_product(p1.begin(), p1.end(), p2.begin(), 0,
                               plus<int>(),  // 外部运算
                               [](int a, int b) { return (a - b) * (a - b); });  // 内部运算
// (1-4)² + (2-5)² + (3-6)² = 27

ACM应用场景:

  • 【向量内积】计算
  • 【欧几里得距离】计算
  • 【相似度】计算

集合操作算法

set_union

// 计算两个有序集合的并集,结果存储在result
auto end_iter = set_union(first1, last1, first2, last2, result);
auto end_iter = set_union(first1, last1, first2, last2, result, comp);
  • 时间复杂度: O(n+m)
  • 空间复杂度: O(n+m)

使用示例:

vector<int> v1 = {1, 2, 3, 5, 7};
vector<int> v2 = {2, 4, 6, 7};
vector<int> result(v1.size() + v2.size());

auto it = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin());
result.resize(it - result.begin());
// result: [1, 2, 3, 4, 5, 6, 7]

set_intersection

// 计算两个有序集合的交集,结果存储在result
auto end_iter = set_intersection(first1, last1, first2, last2, result);
auto end_iter = set_intersection(first1, last1, first2, last2, result, comp);
  • 时间复杂度: O(n+m)
  • 空间复杂度: O(min(n,m))

使用示例:

vector<int> v1 = {1, 2, 3, 5, 7};
vector<int> v2 = {2, 4, 6, 7};
vector<int> result(min(v1.size(), v2.size()));

auto it = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin());
result.resize(it - result.begin());
// result: [2, 7]

set_difference

// 计算第一个集合相对第二个集合的差集,结果存储在result
auto end_iter = set_difference(first1, last1, first2, last2, result);
auto end_iter = set_difference(first1, last1, first2, last2, result, comp);
  • 时间复杂度: O(n+m)
  • 空间复杂度: O(n)

使用示例:

vector<int> v1 = {1, 2, 3, 5, 7};
vector<int> v2 = {2, 4, 6, 7};
vector<int> result(v1.size());

auto it = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin());
result.resize(it - result.begin());
// result: [1, 3, 5]

ACM应用场景:

  • 【集合操作】实现
  • 【离散化】后的区间合并

修改序列算法

copy / copy_if

// 将[first, last)复制到result开始的位置
auto end_iter = copy(first, last, result);

// 复制满足谓词条件的元素
auto end_iter = copy_if(first, last, result, pred);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 4, 5};
vector<int> v2(v.size());
copy(v.begin(), v.end(), v2.begin());  // v2: [1, 2, 3, 4, 5]

// 只复制偶数
vector<int> even;
copy_if(v.begin(), v.end(), back_inserter(even), [](int x) { return x % 2 == 0; });
// even: [2, 4]

transform

// 将[first, last)中的元素应用op操作后存入result
transform(first, last, result, op);

// 将两个范围[first1, last1)和从first2开始的范围应用binary_op后存入result
transform(first1, last1, first2, result, binary_op);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 4, 5};
vector<int> squares(v.size());
transform(v.begin(), v.end(), squares.begin(), [](int x) { return x * x; });
// squares: [1, 4, 9, 16, 25]

vector<int> v1 = {1, 2, 3};
vector<int> v2 = {4, 5, 6};
vector<int> sums(v1.size());
transform(v1.begin(), v1.end(), v2.begin(), sums.begin(), plus<int>());
// sums: [5, 7, 9]

ACM应用场景:

  • 【向量运算】
  • 【数据变换】
  • 【自定义映射】

fill / fill_n

// 用value填充[first, last)
fill(first, last, value);

// 从first开始填充n个value
fill_n(first, n, value);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v(5);
fill(v.begin(), v.end(), 10);  // v: [10, 10, 10, 10, 10]

vector<int> v2(10);
fill_n(v2.begin(), 5, 20);  // v2: [20, 20, 20, 20, 20, 0, 0, 0, 0, 0]

replace / replace_if

// 将[first, last)中的old_value替换为new_value
replace(first, last, old_value, new_value);

// 将[first, last)中满足谓词条件的元素替换为new_value
replace_if(first, last, pred, new_value);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 2, 5};
replace(v.begin(), v.end(), 2, 99);  // v: [1, 99, 3, 99, 5]

replace_if(v.begin(), v.end(), [](int x) { return x > 50; }, 0);
// v: [1, 0, 3, 0, 5]

unique / unique_copy

// 删除[first, last)中的连续重复元素(需要先排序)
auto end_iter = unique(first, last);

// 复制不重复元素到result
auto end_iter = unique_copy(first, last, result);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1) 对于unique,O(n) 对于unique_copy

使用示例:

vector<int> v = {1, 2, 2, 3, 3, 3, 4, 5, 5};
auto it = unique(v.begin(), v.end());
v.erase(it, v.end());  // v: [1, 2, 3, 4, 5]

// 不修改原数组
vector<int> v2 = {1, 1, 2, 2, 2, 3, 4, 4};
vector<int> unique_v(v2.size());
auto it2 = unique_copy(v2.begin(), v2.end(), unique_v.begin());
unique_v.resize(it2 - unique_v.begin());  // unique_v: [1, 2, 3, 4]

ACM应用场景:

  • 【去重】操作
  • 【离散化】预处理

易错点:

  • unique只移除连续重复元素,因此通常需要先排序
  • unique返回一个迭代器,指向不重复序列后的第一个位置,需要使用erase删除多余元素

rotate

// 将[first, middle, last)旋转,使得middle成为序列的第一个元素
auto new_first = rotate(first, middle, last);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 4, 5};
// 将3旋转到首位
rotate(v.begin(), v.begin() + 2, v.end());  // v: [3, 4, 5, 1, 2]

ACM应用场景:

  • 【循环移位】操作
  • 【排列组合】生成

reverse

// 反转[first, last)中的元素顺序
reverse(first, last);

// 反转并将结果保存到result
reverse_copy(first, last, result);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1) 对于reverse,O(n) 对于reverse_copy

使用示例:

vector<int> v = {1, 2, 3, 4, 5};
reverse(v.begin(), v.end());  // v: [5, 4, 3, 2, 1]

// 不修改原数组
vector<int> v2 = {1, 2, 3, 4, 5};
vector<int> rev(v2.size());
reverse_copy(v2.begin(), v2.end(), rev.begin());  // rev: [5, 4, 3, 2, 1]

排列组合算法

next_permutation / prev_permutation

// 生成下一个字典序更大的排列,如果存在返回true,否则返回false
bool has_next = next_permutation(first, last);
bool has_next = next_permutation(first, last, comp);

// 生成上一个字典序更小的排列,如果存在返回true,否则返回false
bool has_prev = prev_permutation(first, last);
bool has_prev = prev_permutation(first, last, comp);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3};
do {
    // 处理当前排列
    for(int x : v) cout << x << " ";
    cout << endl;
} while(next_permutation(v.begin(), v.end()));
/* 输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
*/

// 从大到小生成排列
vector<int> v2 = {3, 2, 1};  // 注意:起始必须是最大排列
do {
    // 处理当前排列
    for(int x : v2) cout << x << " ";
    cout << endl;
} while(prev_permutation(v2.begin(), v2.end()));

ACM应用场景:

  • 【排列枚举】
  • 【状态搜索】
  • 【组合优化】问题

易错点:

  • 使用next_permutation前,需要确保序列已按升序排序,否则无法生成所有排列
  • 使用prev_permutation前,需要确保序列已按降序排序

堆操作算法

make_heap / push_heap / pop_heap / sort_heap

// 将[first, last)范围内的元素转换为一个堆
make_heap(first, last);
make_heap(first, last, comp);

// 将[first, last-1)已经是堆的情况下,将last-1位置的元素加入堆中
push_heap(first, last);
push_heap(first, last, comp);

// 将堆顶元素移到last-1位置,并将[first, last-1)调整为堆
pop_heap(first, last);
pop_heap(first, last, comp);

// 将一个堆转换为排序序列
sort_heap(first, last);
sort_heap(first, last, comp);
  • 时间复杂度:
    • make_heap: O(n)
    • push_heap: O(log n)
    • pop_heap: O(log n)
    • sort_heap: O(n log n)
  • 空间复杂度: 均为O(1)

使用示例:

vector<int> v = {3, 1, 4, 1, 5, 9};

// 创建堆(默认大顶堆)
make_heap(v.begin(), v.end());  // v: [9, 5, 4, 1, 1, 3]

// 添加元素
v.push_back(6);
push_heap(v.begin(), v.end());  // v: [9, 5, 6, 1, 1, 3, 4]

// 移除最大元素
pop_heap(v.begin(), v.end());  // v: [6, 5, 4, 1, 1, 3, 9]
int max_val = v.back();  // 9
v.pop_back();

// 堆排序
sort_heap(v.begin(), v.end());  // v: [1, 1, 3, 4, 5, 6]

ACM应用场景:

  • 【优先队列】的手动实现
  • 【TopK问题】
  • 【多路归并】
  • 【有序区间合并】

易错点:

  • 操作后需要手动维护容器大小(如pop_heap后需要pop_back)
  • STL默认实现的是大顶堆,如需小顶堆,需要自定义比较函数

其他实用算法

min / max / minmax

// 返回两个值中的最小值/最大值/同时返回最小和最大值
T min_val = min(a, b);
T max_val = max(a, b);
pair<T, T> minmax_val = minmax(a, b);
  • 时间复杂度: O(1)
  • 空间复杂度: O(1)

使用示例:

int a = 5, b = 10;
int min_val = min(a, b);  // 5
int max_val = max(a, b);  // 10
auto [m, M] = minmax(a, b);  // m=5, M=10

min_element / max_element / minmax_element

// 返回指向[first, last)中最小/最大/最小和最大元素的迭代器
auto min_it = min_element(first, last);
auto max_it = max_element(first, last);
auto [min_it, max_it] = minmax_element(first, last);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
auto min_it = min_element(v.begin(), v.end());  // 指向第一个1
auto max_it = max_element(v.begin(), v.end());  // 指向9

int min_val = *min_it;  // 1
int min_pos = min_it - v.begin();  // 1 (索引)

auto [min_itr, max_itr] = minmax_element(v.begin(), v.end());
// *min_itr = 1, *max_itr = 9

ACM应用场景:

  • 【区间最值】查询
  • 【最优解】查找

all_of / any_of / none_of

// 检查[first, last)中的所有/任一/没有元素是否满足pred条件
bool all = all_of(first, last, pred);
bool any = any_of(first, last, pred);
bool none = none_of(first, last, pred);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {2, 4, 6, 8, 10};
bool all_even = all_of(v.begin(), v.end(), [](int x) { return x % 2 == 0; });  // true
bool any_gt_5 = any_of(v.begin(), v.end(), [](int x) { return x > 5; });  // true
bool none_neg = none_of(v.begin(), v.end(), [](int x) { return x < 0; });  // true

count / count_if

// 计算[first, last)中等于value的元素个数
int cnt = count(first, last, value);

// 计算[first, last)中满足pred的元素个数
int cnt = count_if(first, last, pred);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
int count_2 = count(v.begin(), v.end(), 2);  // 2
int count_gt_2 = count_if(v.begin(), v.end(), [](int x) { return x > 2; });  // 7

ACM应用场景:

  • 【频率统计】
  • 【条件计数】

for_each

// 对[first, last)中的每个元素应用func操作
for_each(first, last, func);
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

使用示例:

vector<int> v = {1, 2, 3, 4, 5};

// 将所有元素加1
for_each(v.begin(), v.end(), [](int& x) { x += 1; });  // v: [2, 3, 4, 5, 6]

// 打印所有元素
for_each(v.begin(), v.end(), [](int x) { cout << x << " "; });  // 输出: 2 3 4 5 6

ACM应用场景:

  • 【批量操作】
  • 【语法简化】

ACM竞赛中的应用技巧

1. 输入输出加速

// 常用输入输出优化
ios::sync_with_stdio(false);  // 取消同步
cin.tie(nullptr);             // 解除cin与cout的绑定
cout.tie(nullptr);            // 进一步加速

// 快读模板(适用于整数)
inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

2. 算法函数组合应用

// 去重并统计不同元素
vector<int> v = {1, 3, 2, 1, 3, 4, 5, 2};
sort(v.begin(), v.end());
auto it = unique(v.begin(), v.end());
int unique_count = it - v.begin();  // 5个不同元素
v.resize(unique_count);  // v: [1, 2, 3, 4, 5]

// 求第K大的元素(不改变原数组)
vector<int> v2 = {5, 1, 3, 8, 2, 7, 4, 6};
vector<int> temp = v2;
nth_element(temp.begin(), temp.begin() + 2, temp.end(), greater<int>());
int third_largest = temp[2];  // 第3大的元素

// 区间操作:将[l,r]区间内的元素翻倍
vector<int> v3 = {1, 2, 3, 4, 5};
int l = 1, r = 3;  // 对应索引1-3的元素: 2,3,4
transform(v3.begin() + l, v3.begin() + r + 1, v3.begin() + l, 
          [](int x) { return x * 2; });  // v3: [1, 4, 6, 8, 5]

// 检查一个数组是否为另一个数组的子集
vector<int> v4 = {1, 2, 3, 4, 5};
vector<int> v5 = {2, 3, 5};
sort(v4.begin(), v4.end());
sort(v5.begin(), v5.end());
bool is_subset = includes(v4.begin(), v4.end(), v5.begin(), v5.end());  // true

3. 常见优化技巧

// 预分配容器空间以避免频繁重分配
vector<int> v;
v.reserve(100000);  // 预分配空间

// 使用emplace_back代替push_back以避免额外的拷贝操作
vector<pair<int, int>> pairs;
pairs.emplace_back(1, 2);  // 比 pairs.push_back({1, 2}) 更高效

// 使用引用避免不必要的拷贝
for_each(v.begin(), v.end(), [](int& x) { x *= 2; });

// 利用二分查找加速
vector<int> v6 = {1, 3, 5, 7, 9, 11};
// 查找大于等于6的第一个元素
auto it = lower_bound(v6.begin(), v6.end(), 6);  // 指向7

4. 自定义比较函数技巧

// 多维度排序
struct Item {
    string name;
    int priority;
    double value;
};

vector<Item> items = { {"A", 2, 3.5}, {"B", 1, 2.0}, {"C", 2, 1.5} };
sort(items.begin(), items.end(), [](const Item& a, const Item& b) {
    if (a.priority != b.priority) return a.priority < b.priority;  // 首先按优先级升序
    if (a.value != b.value) return a.value > b.value;  // 其次按价值降序
    return a.name < b.name;  // 最后按名称字典序
});

通过系统掌握STL算法函数,可以大幅提高在ACM竞赛中的编码效率和问题解决能力。灵活运用这些工具可以让你的代码更简洁、更高效,从而在有限的比赛时间内解决更多的问题。

记住:选择合适的算法函数不仅能减少代码量,还能避免潜在的错误并提高程序的性能。在实际应用中,理解每个函数的时间复杂度和使用场景尤为重要。