NewCodeTemplate
This commit is contained in:
135
模板/STL/STL相关.md
Normal file
135
模板/STL/STL相关.md
Normal file
@@ -0,0 +1,135 @@
|
||||
### 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);` | 二分 >= 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 <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% 场景够用的核心。熟练后,能让你少写数百行手写代码。建议多刷题记忆模板,考前复习此表即可!如果有特定容器需要更深示例,随时问。
|
||||
Reference in New Issue
Block a user