bitset
它是一种数据结构,用于存储位序列。它以紧凑的方式存储布尔值(0/1),每个布尔值对应一个位。bitset在处理大量布尔值时,可以非常高效的增删改查集合,内存利用率非常高。
初始化
bitset<12> bs;// 指定大小,为12个零
bitset<10> bt(11);//将11转为二进制,赋值给bt
string s=“0111011”;
bitset<10> be(s); //01字符串构造bitset
函数
sizeof(bs) // 结果 4,不超过32,都是4
bs.size() //结果12
bt.count() //有几个1
bs.any() ;//存在1?
bt.none();//不存在1?
bt.test(pos)//pos处是否为1
01变换
bt.set()//全置为1
bt.set(pos)//pos处置为1
bt.reset()//用法与set相反
bt.flip()//逐位取反
bt.flip(pos)
转换输出
int n=bt[3];//最右边是bt[0]
char j=b[3];//错误❌
cout<<bt;
int k=bt;//错误❌
int n=bt.to_ullong();
返回unsigned long类型的值,或者ullong()
特性及支持操作
下标访问
运算符 | & ^ >> << ~
注意:bitset 只能与 bitset 进行位运算,若要和整型进行位运算,要先将整型转换为 bitset。
可以用==,!=比较
状态压缩与 bitset
状态表示:
使用 bitset,每个状态可以用一个整数来表示,这个整数的二进制形式对应于状态的布尔值。
存储空间:
对于 n 个布尔变量的状态,使用 bitset 仅需 n 位存储空间,而不是 n 个独立的布尔变量。
状态遍历:
通过遍历 0 到 2^n - 1 的整数范围,可以枚举所有可能的状态。
应用场景:
适用于需要表示大量组合状态的问题,如背包问题、图的着色问题、状态机等。
示例
在背包问题中,如果有 n 个物品,每个物品可以选择放入或不放入背包,使用一个大小为 n 的 bitset 可以表示所有可能的背包组合。
总结
状态压缩和 bitset 的结合使用,为处理组合问题提供了一种高效且节省空间的解决方案。
习题
简单瞎搞题
思路
找了一道和bitset相关的题,读完还是不知道怎么用bitset去做。看别人的代码,不懂,还是得模拟一遍。看代码中,直接计算p中1的个数就应该知道,每有一种选择就会对应有一个1,出现在p中。因为对于每个数,每次是将 t 和 p 左移i*i(可选择数字的平方)进行或运算,这样可以将不同的选择全部在 t 中呈现出来。当要对下一个数字选择时,将 p 更新为,选择完上一个数字后此时呈现不同选择的 t。而最终的p中1的数量,就能反应出几种选择。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=1e6+10;
bitset<N> p,t;
signed main()
{
IOS
int n;
cin>>n;
p[0]=1;
while(n--)
{
t.reset();
int l,r;
cin>>l>>r;
for(int i=l;i<=r;i++)
t|=p<<(i*i);//t或上不同的i*i,使每一种选择在t中对应一个1
p=t; //一个数字的可能遍历完,更新p
}
cout<<p.count()<<'\n';
}
更多STL内容,可以看这篇博客STL用法总结