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的所有位都置为1

    • bs.set(pos):把bs的pos位置设置为1
  • bs.reset():把bs的所有位都置为0

    • bs.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从低位(右端)开始数

例题:贪心只能过样例

image-20260116150146948

思路:使用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;
}
posted @ 2026-01-16 15:47  江蝶  阅读(2)  评论(0)    收藏  举报