bitset在位运算中的妙用

bitset

以前没有留意到那么好用的东西,可能好久以前做过一次要用bitset优化的题目但是没有记录下来,这次在洛谷基础赛 #21的B题发现可以用bitset或许会更方便于是打算写一个blog概述一下。


bitset在oi wiki


代码解释:

#include <bitset>
//使用bitset必要的头文件
bitset<N> Bs;
//构建一个长度为N(有N个01串)的bitset
//一般默认全为false -> 0

运算符

operator []: 访问其特定的一位。

operator ==/operator !=: 比较两个 bitset 内容是否完全一样。

operator &/operator &=/operator |/operator |=/operator ^/operator ^=/operator ~: 进行按位与/或/异或/取反操作。

注意:bitset 只能与 bitset 进行位运算,若要和整型进行位运算,要先将整型转换为 bitset。

operator <</operator >>/operator <<=/operator >>=: 进行二进制左移/右移。

此外,bitset 还提供了 C++ 流式 IO 的支持,这意味着你可以通过 cin/cout 进行输入输出。

成员函数

count(): 返回 true 的数量。
size(): 返回 bitset 的大小。
test(pos): 它和 vector 中的 at() 的作用是一样的,和 [] 运算符的区别就是越界检查。
any(): 若存在某一位是 true 则返回 true,否则返回 false。
none(): 若所有位都是 false 则返回 true,否则返回 false。
all(): 若所有位都是 true 则返回 true,否则返回 false。
set(): 将整个 bitset 设置成 true。
set(pos, val = true): 将某一位设置成 true/false。
reset(): 将整个 bitset 设置成 false。
reset(pos): 将某一位设置成 false。相当于 set(pos, false)。
flip(): 翻转每一位。(0\leftrightarrow1,相当于异或一个全是 1 的 bitset)
flip(pos): 翻转某一位。

例题


Problem A: P12245 共同兴趣

My accept code:

//P12245
#include <iostream>
#include <bitset>
#define ll long long
using namespace std;
bitset<510> bs[100010];
bitset<510> BS;
bitset<510> Bstag;
ll F[510];
ll dp[510];
int main()
{
    ll N,M,a;
    cin>>N>>M;
    for(int i=1; i<=M; i++)
    {
        cin>>F[i];
        if(F[i])
        bs[1].set(i,true);
		//设置第i(必须是F[i] = 1时)位为1,其余为0
    }
    for(int i=2; i<=N; i++)
    {
        for(int j=1; j<=M; j++)
        {
            cin>>a;
            if(a)
            bs[i].set(j,true);
			//同理,设置a=1时相应位置为1,其余为0
        }
    }
    for(int i=2; i<=N; i++)
    {
        ll Max = 0;
        for(int j=2; j<=N; j++)
        {
            BS = bs[i] & bs[j];
			//进行和运算,求出当前学生与其他学生的最大兴趣值
            //cout<<BS.count()<<endl;
            ll Ftag = BS.count();
			//count()用于输出bs[i]和bs[j]中和运算出来的1的个数
            if(i != j)
            Max = max(Max,Ftag);
        }
        dp[i] = Max; //记录下来
    }
    ll Max = 0;
    for(int r=1; r<=M; r++)
    {
        Bstag = bs[1];
        Bstag.set(r,true);
		//遍历每一位,因为每一位都可能变成1,每次的询问独立,故用 Bstag
        ll ans = 0;
        for(int i=2; i<=N; i++)
        {
            BS = bs[i] & Bstag;
            //cout<<BS.count()<<endl;
            ll Ftag = BS.count();
            if(Ftag >= dp[i])
            ans ++;
        }
        Max = max(Max,ans);
    } cout<<Max;
    return 0;
}
posted @ 2025-04-24 00:12  Supian_owo  阅读(60)  评论(0)    收藏  举报