一、STL 容器
1. set
set 维护的为一个有序集合,其中元素按照大小关系排列.
定义方式如下:
std::set<int> s;
其中 int 为数据类型可替换,但替换的类型必须有定义 $<$ 符号.
常用的操作如下:
①
s.begin() 返回指向集合 $s$ 第一个元素的指针,对应元素元素为 *s.begin(),注意若集合为空则 RE,请谨慎使用.
s.end() 返回集合 $s$ 的结尾指针,注意该指针不指向任何元素.
② s.clear() 表示清空集合 $s$.
③ std::set<int>::iterator it; 表示定义一个集合类型的指针.
④ 遍历 set:
方法一(C++):
for ( std::set<int>::iterator it=s.begin();it!=s.end();it++ )
{
int x=*it;
}
注意:循环判定条件为 it!=s.end(),不可以写 it<s.end(). 同时移动指针应写为 it++ 而不是 it=it+1.
方法二(C++11):
for ( int x:s ) ;
注意:遍历的参数 $x$ 为 $s$ 当中元素的值.
⑤ s.empty() 若集合 $s$ 为空返回 true.
⑥ s.size() 返回集合 $s$ 中的元素个数,使用时需强制类型转换为 int 类型.
⑦ s.insert(x) 插入元素 $x$,若集合中已存在 $x$ 则忽略.
⑧
s.erase(x) 删除元素 $x$,若集合中不存在 $x$ 则 RE,因此需谨慎使用.
s.erase(it) 其中 $it$ 为上述定义的指针. 删除 $it$ 指向的元素,若不存在则 RE.
⑨
s.find(x) 返回一个指针,表示 $x$ 的位置,若不存在 $x$ 则返回 s.end().
s.lower_bound(x) 返回一个指针,表示第一个大于等于 $x$ 的数的位置. 若不存在则返回 s.end().
s.upper_bound(x) 返回一个指针,表示第一个大于 $x$ 的数的位置. 若不存在则返回 s.end().
⑩
s.count(x) 若集合 $s$ 包含 $x$ 则返回 true.
2. multiset
维护可重集合,大部分操作与 set 相同.
区别如下:
① s.size() 返回集合 $s$ 中的元素个数,注意同种元素会被算多次.
② s.insert(x) 插入元素 $x$.
③
s.erase(x) 删除所有元素 $x$.
s.erase(it) 删除 $it$ 指向的 $x$,
④ s.count(x) 返回集合中 $x$ 的个数.
补充:
multiset 常用的删除一个元素 $x$ 的方法为先用 find() 找到该元素的指针,再 erase() 删去指针即可. 代码如下:
s.erase(s.find(x));
3. map
map 维护的是一个映射关系,简单来说就是一个下标类型任意的数组.
定义类似于 set 与 multiset:
std::map<int,int> f;
此处前一个 int 表示数组下标的类型,需定义 $<$ 运算符,后一个 int 表示数组的值的类型,无要求.
常用操作如下:
① f[x] 返回 $x$ 对应的值(地址),与数组用法相同.
② f.count(x), f.clear(), f.size(), f.erase() 同 set 用法.
③ 由于 map 存的是一组映射关系,因此其中的每个元素为一个 pair 类型,即一对元素,所有返回的指针均为 pair 类型,使用方式如下:
p.first 表示返回 pair 类型 $p$ 的第一个元素,p.second 返回第二个元素. 对应到 map 有:
若定义 f[x]=y,则对应的指针为 (pair){x,y}.
其余大部分用法同 set.
上述三个 STL 容器的单次操作的效率均为 $O(log n)$ 级别(clear()为 $O(1)$),其中 $n$ 为元素个数. 具体实现采用红黑树的做法,常数较大,如遇到卡常题目不建议使用.