常见函数及语法
列举一些个人认为比较实用的函数以及语法知识。
函数
二分查找函数
lower_bound
找到有序数组中第一个大于等于目标值的数的位置。如果找不到,返回最后一个值的后一个位置。如果是数组,使用格式如下:
int p = lower_bound(a+1, a+1+n, k) - a;
上述代码的含义是,在长度为 n ,下标从 1 开始的 a 数组中,找到第一个大于等于 k 的位置。如果数组中没有合法数字,会返回 n+1。
在 vector 里面使用:int p = lower_bound(a.begin(), a.end(), m) - a.begin();
在 set 里面使用:set<int>::iterator it=a.lower_bound(m)
。由于 set 不支持随机访问,所以只能返回迭代器,如果找不会返回 a.end()
,找到了若想使用数字,要用 *it
。
upper_bound
找到第一个大于元素的位置,格式同 lower_bound。
排列/排序相关
sort
默认从小到大排序,但是不稳定,需要注意,经常使用。
next_permutation
返回当前排列的下一个排列,一般在枚举全排列时使用,在使用前需要进行从小到大排序。
格式:
do{
}while(next_permutation(a+1, a+1+n));
nth_element
使用格式:nth_element(a+l,a+k,a+r)
.
将区间 \([l,r]\) 中的第 \(k\) 大元素放在第 \(k\) 个位置上,左边都比这个位置上的数下,右边都比这个位置上的数字大,时间复杂度 \(O(n)\) 。
如果不是为了卡常,写个 memcpy+sort 就可以过了。。。
mem家族
memset
数组赋值函数,一般这样使用:
memset(a,0,sizeof(a));
表示将 a 数组全部赋上 0 的值,但是要注意,只有赋 0 和 -1 才能真正赋值到 0 或 -1,赋值别的数是不能实现真正的区间赋值的。
在初始化 \(dp\) 数组时也常这样使用:
memset(dp, 0x3f, sizeof(dp));
memset(dp, -0x3f, sizeof(dp));
赋值 0x3f
的好处是:两个 0x3f
加起来也不会整形溢出,而且大约在 \(10^9\) 以上,可以满足绝大多数\(dp\) 题目的要求。
memcpy
使用格式,memcpy(b,a,sizeof(a))
.
表示将 a 数组的值复制到 b 数组,这里要注意,a 和 b 数组必须是同一维的。
常用于滚动数组优化空间。
语法
友元
在写结构体的时候,若想重载某个运算符,用传统写法很不直观。“友元”这个概念可以帮助我们写出直观的重载运算符。
friend node operator + (node a, node b) {
}
上面的例子是:重载结构体 node 的 + 运算符,最终返回一个 node 类型的值。
友元可以用作写大整数类,将高精度计算封装成正常的加减乘除运算。
也可以实现复杂状态下的 \(dp\) 数组合并,使得代码写起来更加直观好懂。
\(To\;be\;continue...\)