bitset 可以用来进行一些玄学优化,所以又被称为骗分神器。还能用来卡常
它可以巧妙利用位运算跑得快的优势,而且没有普通整数最高 64 位的限制。(只需要在初始化时定义长度)
而且很全能,还可以当 bool 数组使用(可以使用 []
运算符直接访问元素)。
你能把整数转成 bitset,当你又想转成整数时也能轻松转换。与字符串互转也不在话下。
初始化
#include <bitset>
std::bitset<N> b; // 初始化一个长度为 N 的 bitset,名称为 b
还有其他初始化方式
using namespace std;
bitset<N> b(u); // 作为一个无符号 int 的副本初始化
// 以下需包含 string 头文件
bitset<N> b(s); // 作为一个 string 的副本初始化
bitset<N> b(s, pos); // 作为 s 中从位置 pos 开始位的副本初始化
bitset<N> b(s, pos, n); // 作为 s 中从位置 pos 开始的 n 个位的副本
运算
支持位运算!!!
就像一个普通的整数一样,可以进行与(&)、或(|)、异或(^)以及左移(<<)、右移(>>)运算。
成员函数表
注:二进制位从 0 开始,最右边一位是第 0 位。
Member functions | Definition |
---|---|
any() | 判断是否存在置为 1 的二进制位 |
none() | 判断是否不存在置为 1 的二进制位 |
count() | 二进制位为 1 的个数 |
size() | 二进制位的个数 |
b[pos] | 访问 pos 处的二进制位 |
test(pos) | 判断在 pos 处的二进制位是否为 1 |
set() | 把所有二进制位都置为 1 |
set(pos) | 把在 pos 处的二进制位置为 1 |
set(pos, x) | 把在 pos 处的二进制位置为 x |
reset() | 把所有二进制位都置为 0 |
reset(pos) | 把在 pos 处的二进制位置为 0 |
flip() | 把所有二进制位都取反 |
flip(pos) | 把在 pos 处的二进制位取反 |
to_ulong() | 用同样的二进制位返回一个 unsigned long 值 |
to_ullong() | 同上,只是返回一个 unsigned long long 值 |
to_string() | 返回一个 string 字符串 |
os << b | 把 b 的位集输出到 os 流 |
更多用法见 cplusplus.com
附:位运算技巧
注意:由于位运算优先级很低,所以要勤加括号。
判断两个数是否同号
!((x ^ y) >> 31)
交换两个数
a ^= b, b ^= a, a ^= b
求一个数 n 的绝对值
int
型右移 31 位取出符号(n ^ (n >> 31)) - (n >> 31)
提取 lowbit
一个数 x 在二进制下最右边一个1开始至最低位的那部分是 lowbit(x)
应用:树状数组、遍历集合
lowbit(x) = x & (x ^ (x - 1))
lowbit(x) = x ^ (x & (x - 1))
lowbit(x) = x & -x
提取末尾(低位)连续的 1
对一个数 +1 时,其末尾连续的 1 会变成 0,末位的 0 会变成 1。x & (x ^ (x + 1))