bitset学习
bitset学习
背景
使用bitset要用到std.
bitset是一个存储0/1的大小不可变容器,而vector<bool>是可变的
使用bitset主要是因为可以用来优化常熟时间(变为原本时间/机器位数),并且有很多方便的库函数
声明
指定头文件
#include<bitset>
指定大小
std::bitset<width>name;
例如:bitset<1000>bs;
构造函数
- bitset():每一位都是false.如bitset<6>bs;(bs=000000)
- bitset(unsigned long val):将其设置为val的二进制形式.如bitset<6>bs(5);(bs=000101)
- bitset(const string& str):将其设置为 01串str.如bitset<6>bs("101");(bs=000101)
运算符
- 使用bs[]访问其特定一位 从低位(右端)开始数
- 两个bitset类型可以使用==或者!=判断是否相等
- 进行位运算,但是bitset只能和bitset运算,&|^~或者
&=|=^= - 二进制的左右移
<<>><<=>>=
还可以通过cin、cout流式输出,
输入的要求是
- 只能输入0/1字符串;
- 如果不足会在高位自动补0,如果越界了会读入前面长度为位宽的0/1串,后面的还在输入缓冲区里面
- 如果碰到非0/1的字符会自动舍弃非法字符后面的,将前面的直接读入,后面的还在输入缓冲区里面
输出的是所有位宽上的值
成员函数
-
.count():返回1的数量 -
.size():返回大小 size是位宽,而不是最高位1 -
.any():是否存在某一位为1,存在则返回true -
.none():若所有位数都为0则返回true -
.all():若所有位数都为1则返回1 -
bs.set():把bs的所有位都置为1bs.set(pos):把bs的pos位置设置为1
-
bs.reset():把bs的所有位都置为0bs.reset(pos):把bs的pos位置设置为0
-
bs.flip():翻转bs的每一位(0变1,1变0这种)bs.flip(pos):翻转bs的pos位置
-
bs.to_string():这个返回的是bs转换成 01字符串 的形式 -
bs.to_ulong():返回bs转换成unsigned long的形式 -
bs.to_ullong():返回bs转换成unsigned long long的形式 -
\_Find_first():返回bs变量里面第一个1所在的位置,如果没有直接返回bs变量的size从低位(右端)开始数 -
_Find_next(pos):返回pos位置后面(不包括pos)第一个1所在的位置,如果pos后面没有1,则返回bs变量的size从低位(右端)开始数
例题:贪心只能过样例

思路:使用DP解决问题,100*100+...在n为100时最高也只有1e6,所以开一个bitset数组,大小为n,长度为1e6,相当于集合论里面的布尔表示法一样, 如果第i位为1, 就表示数字i在这个集合里面.
要在前i个数里面凑出平方和为j的,如果第j个数字取k,那么只要前i-1个数里面取得j-k*k即可,所以状态转移方程就是f[i][k]=f[i-1][j-j*j].放到bitset里面加上k*k就是<<k*k,f[i]去对f[i-1]进行或运算即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define vi vector<int>
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define endl '\n'
const int INF=1e18,N=2e5,MOD=1e9+7;
bitset<101*101*101>f[101];
void solve(){
int n;
cin>>n;
vi a(n+1),b(n+1);
for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
f[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=a[i];j<=b[i];j++){
f[i]|=f[i-1]<<(j*j);
}
}
cout<<f[n].count()<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T=1;
// cin>>T;
while(T--)
solve();
return 0;
}

浙公网安备 33010602011771号