前言 #
大部分内容都是从知乎看来的。这里做一个汇总。
以后看见别的也会补充进来,未完待续。
二进制相关 #
__builtin_popcount(num)
返回 num
二进制中 1 的个数。
lower_bound 与 upper_bound 的用法 #
普通用法感觉众所周知,但直到退役我都不知道怎么用来在升序数组中找第一个小于某个数或者小于等于某个数的数。
下面的例子只有 upper_bound
,要等于号也成立的话,把 upper_bound
改成 lower_bound
即可。
升序数组中,找第一个大于某个数的数的迭代器:
upper_bound(arr.begin(), arr.end(), num)
升序数组中,找第一个小于某个数的数的迭代器:
upper_bound(arr.rbegin(), arr.rend(), num, greater<int>())
降序数组中,找到第一个大于某个数的数的迭代器:
upper_bound(arr.rbegin(), arr.rend(), num)
降序数组中,找到第一个小于某个数的数的迭代器:
upper_bound(arr.begin(), arr.end(), num, greater<int>())
总结一下就是,当你要找的数在 num
左边时,要用反向迭代器,当在右侧时则不用。而是小于号时,则用的是 greater<int>()
,否则不用。
(数组没有反向迭代器怎么办?说得好,我选择手写二分。)
寻找数组最大(小)值 #
懒得写循环了。
数组最大值:*max_element(arr.begin(), arr.end())
数组最小值:*min_element(arr.begin(), arr.end())
普通数组的话,填指针也是可以的。
前缀和与差分 #
前缀和:
partial_sum(arr.begin(), arr.end(), back_inserter(res))
// res[0] = arr[0], res[1] = arr[0] + arr[1] ...
差分:
adjacent_difference(arr.begin(), arr.end(), back_inserter(res))
// res[0] = arr[0], res[1] = arr[1] - arr[0] ...
普通数组的话,第三个参数直接填数组名(指针)就行了。
初始化相关 #
除了很常见的 memset
,其实还有 fill
(好像这个也不是很少见)
fill(arr.begin(), arr.end(), num)
速度可能比不上 memset
,但胜在可以初始化为其他值。
还有就是递增赋值,在初始化并查集的时候有用:
iota(arr.begin(), arr.end(), 0);
// arr[0] = arr[0], arr[1] = 1, arr[2] = 2 ...
递减的话,填入反向迭代器就行。