[算法学习]模板-STL与基础算法
[算法学习]模板-STL与基础算法
在 OI 赛制(如蓝桥杯)中,绝对不要去手写队列、堆或者红黑树。C++ 的标准模板库 (STL) 就是官方提供的黑盒 API。熟练调用它们,能把 $O(N^2)$ 的暴力代码瞬间降维到 $O(N \log N)$。
📦 核心容器 API (Containers)
1. 动态数组 vector (图论基建)
物理内存连续的变长数组。它是图论中替代“二维数组存图”的终极武器(用于构建邻接表)。
1 | |
2. 队列 queue (BFS 波纹引擎)
先进先出 (FIFO) 的数据结构。广度优先搜索 (BFS) 的唯一核心驱动器。
1 | |
3. 优先队列 priority_queue (贪心与 Dijkstra 外挂)
底层是一棵“二叉堆”。无论你按什么顺序把数据扔进去,它总能以 $O(\log N)$ 的速度把最大(或最小)的元素浮到顶端。
1 | |
🚨 高危防雷:priority_queue 的反直觉排序 (以贪心区间调度为例)
在处理贪心问题时(比如经典的**“活动安排/区间调度问题”**:给 $N$ 个比赛的开始和结束时间,问最多能参加几个),我们经常需要自定义排序规则。
贪心核心思想:谁结束得越早,我就越先选谁!因为结束得越早,留给后面比赛的时间就越多。所以必须按结束时间从小到大排序。
【极其危险的暗雷】:priority_queue 的排序重载逻辑,和 sort 是完全相反的!
- 如果用
sort,升序你会写A.endtime < B.endtime;(符合直觉)。 - 但
priority_queue默认是大根堆(最大的在上面)。为了让结束时间最小的浮在堆顶,变成小根堆,你的比较逻辑必须反着写>!
实战终极模板(自写结构体 + 仿函数重载):
1 | |
4. 集合 set 与 映射 map (红黑树 / 状态压缩)
底层由红黑树实现,维护一个严格有序且不重复的内存空间。
1 | |
⚙️ 核心算法库 <algorithm>
必须引入头文件 #include <algorithm>。这是蓝桥杯前两道大题白嫖分数的绝对利器。
1. 极速排序 sort
采用内省式排序(快排+堆排+插入排序的结合体),时间复杂度极度稳定的 $O(N \log N)$。
1 | |
2. 全排列生成器 next_permutation
暴力穷举的终极外挂!能够原地将数组变成字典序的下一个排列。有了它,一半的 DFS 全排列题目都可以免手写。
1 | |
🚀 实战进阶补丁 (Hotfix)
🛠️ 补丁 1:STL 的致命弱点 —— I/O 阻塞
C++ 的 cin 和 cout 为了兼容 C 语言的 stdio,底层加了极重的同步锁。在读取超过 $10^5$ 级别的数据时,极易导致 TLE(超时)。
物理防御:在 main 函数的第一行,永远无脑加上这句“解除封印”的代码:
1 | |
🛠️ 补丁 2:map 的内存爆炸陷阱
在使用 map<int, int> mp; 时,如果你只是想查询某个键是否存在,绝对不要写 if(mp[x] == 1)!
因为 mp[x] 会强行在红黑树里为你开辟一个默认值为 0 的新节点,瞬间吞噬内存。
正确判定姿势:
1 | |