c++98~c++17 的一些好用的用法--zhengjun

c++98

find(bg,ed,val)

返回指向第一个等于 \(val\) 的元素的指针。
时间复杂度 \(O(n)\)

fill(bg,ed,val)

\([bg,ed)\) 之间的所有元素赋值为 \(val\)

复杂度为 \(O(n)\),常数略大于 memset

copy(bg1,ed1,bg2)

\([bg_1,ed_1)\) 中的元素复制到 \(bg_2\)
复杂度 \(O(n)\)

max_element/min_element(bg,ed)

返回指向 \([bg,ed)\) 中最大 / 最小的元素的指针。

时间复杂度 \(O(n)\)

第三个参数可传入比较函数。

求数组最大值就可以直接写:*max_element(a+1,a+n+1)

merge(bg1,ed1,bg2,ed2,bg3)

\([bg_1,ed_1)\)\([bg_2,ed_2)\) 是两个有序序列,对其进行归并并存入 \(bg_3\)

不能够原地归并,若要原地归并请使用 inplace_merge

时间复杂度 \(O(ed_1-bg_1+ed_2-bg_2)\)

可以传入第六参数作为比较函数。

inplace_merge(bg,md,ed)

\([bg,md)\)\([md,ed)\) 归并排序,并存入 $$bg$。

时间复杂度 \(O(n)\),需要 \(O(n)\) 的额外空间。

当空间不足时使用 \(O(n\log n)\) 的原地排序。

常数较小,可能比手写的还快。

可以传入第四个参数作为比较函数。

常用于 CDQ 分治等分治算法,非常好用。

__lg(x)

返回 \(\lfloor \log_2x\rfloor\)
时间复杂度 \(O(1)\)
常用于实现倍增、二进制运算等。

__gcd(x,y)

返回 \(\gcd(x,y)\)
复杂度是对数级别的,常数较小。
注意,返回值的符号 不一定 是正。
在 C++17 之前都是很常用的。

accumulate(bg,ed,val)

\([bg,ed)\) 中的所有所有元素与初始值 \(val\) 相加,返回这个和。

时间复杂度 \(O(n)\)

可以传入第四个参数作为加法。

可以用于求序列和,但注意,该函数返回值与 \(val\) 类型一致,意味着你要注意 long long 的问题:

accumulate(bg,ed,0);//返回值是 int,可能溢出
accumulate(bg,ed,0ll);//返回值是 long long

partial_sum(bg1,ed1,bg2)

\([bg_1,ed_1)\) 做前缀和并存入 \([bg_2,bg_2+ed_1-bg_1)\)
时间复杂度 \(O(n)\)
可以传入第四个参数作为加法。
可以原地求前缀和。

adjacent_difference(bg1,ed1,bg2)

\([bg_1,ed_1)\) 求差分并存入 \([bg_2,bg_2+ed_1-bg_1)\)
时间复杂度 \(O(n)\)
可以传入第四个参数作为减法。
可以原地差分。

__builtin 家族

这里的内容并不在 C++ 标准中,全部都是 GNU 的私货,若使用其它编译器则可能无法通过编译。

如果 \(x\) 的类型是 long long,请务必使用 __builtin_xxxll(x)(如 __builtin_popcountll(x)),否则将可能造成 FST 等严重后果。

__builtin_popcount(x)

返回 \(x\) 在二进制下 \(1\) 的个数。

时间复杂度有说 \(O(\log\log x)\) 的,也有说 \(O(1)\) 的。

一定比手写的快。

__builtin_parity(x)

返回 \(x\) 在二进制下 \(1\) 个数的奇偶性。
时间复杂度 \(O(1)\),快于 __builtin_popcount(x)&1

__builtin_ffs(x)

返回二进制下最后一个 \(1\) 是从后往前第几位。
时间复杂度 \(O(1)\)

__builtin_ctz(x)

返回二进制下后导零的个数,\(x=0\) 时 UB。
时间复杂度 \(O(1)\)

__builtin_clz(x)

返回二进制下前导零的个数,\(x=0\) 时UB。
时间复杂度 \(O(1)\)

shrink_to_fit

vector/deque/string/basic_stringshrink_to_fit 可以使其 \(capacity\) 调整为 \(size\) 的大小,如:

max(l)/min(l)

l 是一个初始化列表,这个函数返回 l 中最大 / 最小的元素。
时间复杂度 \(O(size_l)\)
在多个元素求最大 / 最小时非常好用:max({a,b,c})

iota(bg,ed,val)

\([bg,ed)\) 中的元素依次赋值为 \(val,val+1,val+2,\cdots\)
时间复杂度 \(O(n)\)
常用于给并查集初始化。

prev(it)/next(it)

返回迭代器 \(it\) 的前驱 / 后继。

复杂度与 ++/-- 的复杂度相同,取决于容器。

begin(container)/end(container)

返回容器 \(\texttt{container}\)begin()end()

复杂度取决于容器。

作用就是相比原先要短一个字节。

mt19937 gen(chrono::system_clock::now().time_since_epoch().count());

hypot(x,y)

返回 \(\sqrt{x^2+y^2}\)
常用于求两点之间的距离,非常方便。

set/map 的 merge

将一个 set/map 并入另一个,若将 \(t\) 并入 \(s\) ,则所有 \(t\) 中未在 \(s\) 里出现的元素将被插入 \(s\),并在 \(t\) 中被删除。

对于 s.merge(t),复杂度为 \(O(|t|\log(|s|+|t|))\)

gcd(x,y)/lcm(x,y)

返回 \(\gcd(|x|,|y|)\) / \(\operatorname {lcm}(|x|,|y|)\) 的值。
复杂度对数级别的。
保证了返回值的符号是正。
\(lcm\) 的实现是先除后乘。

size(container)/empty(container)

返回一个容器的 size() / 是否为空。
复杂度取决于容器。

hypot(x,y,z)

返回 \(\sqrt{x^2+y^2+z^2}\)
复杂度 \(O(1)\)
常用来求三维中两点距离。

posted @ 2022-08-08 13:44  A_zjzj  阅读(261)  评论(0编辑  收藏  举报