### STL 在考场(OI/ACM)中的要点总结 在算法竞赛考场上,STL 是 C++ 的核心优势,能大幅节省时间、减少手写数据结构的错误。重点掌握常用容器和算法的操作、时间复杂度,以及常见坑。以下是针对考场的精炼总结,优先列出最常用的部分,并详细说明函数及其使用方法(包括示例代码)。 #### 1. 常用容器(优先掌握 vector、string、priority_queue、set、map) | 容器 | 头文件 | 特点与时间复杂度 | 考场用途 | |---------------|-----------------|-------------------------------------------|---------------------------| | **vector** | `` | 动态数组,支持随机访问 | 代替数组,最常用 | | **string** | `` | 动态字符串 | 字符串处理 | | **priority_queue** | `` | 优先队列(默认大根堆) | Dijkstra、贪心选最大/小 | | **set** | `` | 有序集合(不重复,红黑树) | 自动排序、去重、二分 | | **map** | `` | 有序键值对(红黑树) | 映射、计数 | | **queue** | `` | 普通队列(FIFO) | BFS | | **stack** | `` | 栈(LIFO) | DFS、括号匹配 | | **deque** | `` | 双端队列 | 滑动窗口等 | **vector 详细函数与使用** ```cpp #include vector v; // 定义 v.push_back(x); // 末尾插入 O(1) amortized v.pop_back(); // 末尾删除 O(1) v.size(); // 元素个数 v.empty(); // 是否为空 v.clear(); // 清空 v.front(); v.back(); // 首/尾元素 v[i]; // 随机访问 O(1) v.insert(it, x); // 迭代器位置插入 O(n) v.erase(it); // 删除迭代器位置 O(n) sort(v.begin(), v.end()); // 排序(常配合使用) v.resize(n); // 调整大小 ``` 考场技巧:预分配空间 `vector v(n);` 或 `v.reserve(n);` 避免多次扩容。 **string 详细函数与使用** ```cpp #include string s = "abc"; s += "def"; // 拼接 s.push_back('x'); // 末尾加字符 s.size() / s.length(); // 长度 s.substr(pos, len); // 子串,从pos开始len长 s.find(str); // 查找子串,返回位置(未找到string::npos) s.erase(pos, len); // 删除子串 s.insert(pos, str); // 插入 s.clear(); char c = s[i]; // 访问 ``` 考场常用:字符串反转 `reverse(s.begin(), s.end());` **priority_queue 详细函数与使用**(考场最常用之一) ```cpp #include priority_queue pq; // 大根堆(默认,最大值在顶) priority_queue, greater> pq; // 小根堆(最小值在顶) pq.push(x); // 插入 O(log n) pq.pop(); // 删除顶 O(log n) pq.top(); // 访问顶 pq.empty(); pq.size(); // 自定义结构体(pair 或 struct) priority_queue> pq; // 默认第一大,第二大 priority_queue, vector>, greater>> pq; // 小根 // 自定义比较(复杂结构体) struct Node { int val, id; }; struct cmp { bool operator()(const Node& a, const Node& b) { return a.val < b.val; // 大根堆(改>为小根) } }; priority_queue, cmp> pq; ``` 考场坑:小根堆写 `greater >` 时中间加空格,避免 `>>` 编译错误。 **set 详细函数与使用** ```cpp #include set st; // 有序不重复 multiset mst; // 允许重复 st.insert(x); // 插入 O(log n) st.erase(x); // 删除值 O(log n)(或 st.erase(it);) st.find(x); // 查找,返回迭代器(未找到 st.end()) st.count(x); // 计数(set为0/1) st.lower_bound(x); // >= x 的最小迭代器 st.upper_bound(x); // > x 的最小迭代器 st.begin(); st.end(); // 迭代器 ``` 考场技巧:去重 `sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end());` **map 详细函数与使用** ```cpp #include map mp; // key有序 unordered_map ump; // 无序(C++11,平均O(1),但最坏O(n)) mp[key] = val; // 插入/修改(不存在自动插入) mp.insert({key, val}); mp.erase(key); mp.find(key); // 未找到 mp.end() mp.count(key); mp.lower_bound(key); // >= key ``` 考场常用:计数、离散化。 #### 2. 常用算法(头文件 ``) | 函数 | 用法示例 | 说明与复杂度 | |-----------------------|---------------------------------------|-----------------------| | **sort** | `sort(v.begin(), v.end());` | O(n log n),自定义 `sort(v.begin(), v.end(), cmp);` | | **reverse** | `reverse(v.begin(), v.end());` | 反转 O(n) | | **max_element / min_element** | `*max_element(v.begin(), v.end());` | 返回迭代器 O(n) | | **lower_bound** | `lower_bound(v.begin(), v.end(), x);` | 二分 >= x,O(log n)(需有序) | | **upper_bound** | `upper_bound(v.begin(), v.end(), x);` | 二分 > x | | **unique** | `v.erase(unique(v.begin(), v.end()), v.end());` | 去重(需先sort) | | **next_permutation** | `do { ... } while(next_permutation(v.begin(), v.end()));` | 全排列 | | **fill** | `fill(v.begin(), v.end(), val);` | 填充 | 考场技巧:二分常用 lower_bound,返回迭代器减 begin() 得位置。 #### 3. 考场通用要点与坑 - **头文件**:常用 `#include `(万能头,竞赛专用)。 - **命名空间**:`using namespace std;` - **迭代器**:auto 遍历 `for(auto &x : v) x=...;`(可修改)。 - **pair**:`pair p = {a,b};` 或 `make_pair(a,b);` 常用于 priority_queue。 - **时间复杂度**:set/map O(log n),vector O(1) 访问,注意 n<=1e5~1e7 时别用 O(n^2)。 - **输入加速**:`ios::sync_with_stdio(false); cin.tie(0);` - **常见错误**:忘清空容器、迭代器失效、优先队列比较写错、>> 空格问题、爆 int 用 long long。 这些是考场 90% 场景够用的核心。熟练后,能让你少写数百行手写代码。建议多刷题记忆模板,考前复习此表即可!如果有特定容器需要更深示例,随时问。