Files
Data-Structure/模板/STL/STL相关.md
2025-12-16 20:36:27 +08:00

135 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### STL 在考场OI/ACM中的要点总结
在算法竞赛考场上STL 是 C++ 的核心优势,能大幅节省时间、减少手写数据结构的错误。重点掌握常用容器和算法的操作、时间复杂度,以及常见坑。以下是针对考场的精炼总结,优先列出最常用的部分,并详细说明函数及其使用方法(包括示例代码)。
#### 1. 常用容器(优先掌握 vector、string、priority_queue、set、map
| 容器 | 头文件 | 特点与时间复杂度 | 考场用途 |
|---------------|-----------------|-------------------------------------------|---------------------------|
| **vector** | `<vector>` | 动态数组,支持随机访问 | 代替数组,最常用 |
| **string** | `<string>` | 动态字符串 | 字符串处理 |
| **priority_queue** | `<queue>` | 优先队列(默认大根堆) | Dijkstra、贪心选最大/小 |
| **set** | `<set>` | 有序集合(不重复,红黑树) | 自动排序、去重、二分 |
| **map** | `<map>` | 有序键值对(红黑树) | 映射、计数 |
| **queue** | `<queue>` | 普通队列FIFO | BFS |
| **stack** | `<stack>` | 栈LIFO | DFS、括号匹配 |
| **deque** | `<deque>` | 双端队列 | 滑动窗口等 |
**vector 详细函数与使用**
```cpp
#include <vector>
vector<int> 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<int> v(n);``v.reserve(n);` 避免多次扩容。
**string 详细函数与使用**
```cpp
#include <string>
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 <queue>
priority_queue<int> pq; // 大根堆(默认,最大值在顶)
priority_queue<int, vector<int>, greater<int>> pq; // 小根堆(最小值在顶)
pq.push(x); // 插入 O(log n)
pq.pop(); // 删除顶 O(log n)
pq.top(); // 访问顶
pq.empty(); pq.size();
// 自定义结构体pair 或 struct
priority_queue<pair<int,int>> pq; // 默认第一大,第二大
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq; // 小根
// 自定义比较(复杂结构体)
struct Node {
int val, id;
};
struct cmp {
bool operator()(const Node& a, const Node& b) {
return a.val < b.val; // 大根堆(改>为小根)
}
};
priority_queue<Node, vector<Node>, cmp> pq;
```
考场坑:小根堆写 `greater<int> >` 时中间加空格,避免 `>>` 编译错误。
**set 详细函数与使用**
```cpp
#include <set>
set<int> st; // 有序不重复
multiset<int> 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>
map<int, int> mp; // key有序
unordered_map<int, int> 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. 常用算法(头文件 `<algorithm>`
| 函数 | 用法示例 | 说明与复杂度 |
|-----------------------|---------------------------------------|-----------------------|
| **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);` | 二分 >= xO(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 <bits/stdc++.h>`(万能头,竞赛专用)。
- **命名空间**`using namespace std;`
- **迭代器**auto 遍历 `for(auto &x : v) x=...;`(可修改)。
- **pair**`pair<int,int> 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% 场景够用的核心。熟练后,能让你少写数百行手写代码。建议多刷题记忆模板,考前复习此表即可!如果有特定容器需要更深示例,随时问。