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

7.2 KiB
Raw Blame History

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 详细函数与使用

#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 详细函数与使用

#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 详细函数与使用(考场最常用之一)

#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 详细函数与使用

#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 详细函数与使用

#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=...;(可修改)。
  • pairpair<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% 场景够用的核心。熟练后,能让你少写数百行手写代码。建议多刷题记忆模板,考前复习此表即可!如果有特定容器需要更深示例,随时问。