Bitset小结 (POJ2443 & HDU4920)

学了下bitset用法,从网上找的一些bitset用法,并从中调出一些常用的用法。

构造函数
bitset<n> b;
 b有n位,每位都为0.参数n可以为一个表达式.
如bitset<5> b0;则"b0"为"00000";

bitset<n> b(unsigned long u);
 b有n位,并用u赋值;如果u超过n位,则顶端被截除
如:bitset<5>b0(5);则"b0"为"00101";
 
bitset<n> b(string s);
 b是string对象s中含有的位串的副本
string bitval ( "10011" );
bitset<5> b0 ( bitval4 );
则"b0"为"10011";

 

bitset<n> b(s, pos, num);
 b是s中从位置pos开始的num个位的副本,如果num<n,则前面的空位自动填充0;
string bitval ("11110011011");
bitset<6> b0 ( bitval5, 3, 6 );
则"b0" 为 "100110";


os << b
 把b中的位集输出到os流
os >>b
输入到b中,如"cin>>b",如果输入的不是0或1的字符,只取该字符前面的二进制位.

 

bool any( ) 
 是否存在置为1的二进制位?和none()相反
 
bool none( ) 
是否不存在置为1的二进制位,即全部为0?和any()相反.
 
size_t count( )
二进制位为1的个数.
 
size_t size( )
 二进制位的个数

flip()
 把所有二进制位逐位取反
 
flip(size_t pos)
 把在pos处的二进制位取反
 
bool operator[](   size_type Pos )
 获取在pos处的二进制位
 
set()
 把所有二进制位都置为1
 
set(pos)
 把在pos处的二进制位置为1
 
reset()
 把所有二进制位都置为0
 
reset(pos)
 把在pos处的二进制位置为0

 

注意:bitset只能与bitset运算,不能与数运算

 
另外找到两题相关的bitset题目,确实bitset用上之后能使代码量大大减少。
 
POJ2443:
思路:数最大10000,给每个数开个bitset<1000>存其是否属于相应位上的集合
  之后ans即 两个bitset与运算即可
 
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <map>
#include <deque>
#include <bitset>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define INF 0x3f3f3f3f

using namespace std;

bitset<1005> bit[10005];
int N,M,T,a,b;
int main()
{
    scanf("%d",&N);
    for(int i=0; i<N; i++)
    {
        scanf("%d",&M);
        for(int j=0; j<M; j++)
        {
            scanf("%d",&a);
            bit[a].set(i);
        }
    }
    scanf("%d",&T);
    for(int i=0; i<T; i++)
    {
        scanf("%d%d",&a,&b);
        if((bit[a]&bit[b]).any())
            printf("Yes
");
        else
            printf("No
");
    }
    return 0;
}
View Code

HDU4920:

思路:矩阵化为0,1,2为值的矩阵,bitset存储0,1,2在矩阵上位置。

   则可通过count快速算出1*1,1*2,2*1,2*2的个数,容易得到答案。

注:此题其余优化思路是将B矩阵转置,据说是加快数组访问速度,即转置后每次访问+1而非+n,其神奇的效果不言而喻。当然仅限于这种常数级优化!

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <map>
#include <deque>
#include <bitset>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define INF 0x3f3f3f3f

using namespace std;

bitset<805> A[805][3],B[805][3];
int N,k,C;

int main()
{
    while(scanf("%d",&N)!=EOF && N)
    {
        for(int i=0; i<N; i++)
            for(int j=0; j<3; j++)
            {
                A[i][j].reset();
                B[i][j].reset();
            }

        for(int i=0; i<N; i++)
            for(int j=0; j<N; j++)
            {
                scanf("%d",&k);
                A[i][k%3].set(j);
            }
        for(int i=0; i<N; i++)
            for(int j=0; j<N; j++)
            {
                scanf("%d",&k);
                B[j][k%3].set(i);
            }
        for(int i=0; i<N; i++)
            for(int j=0; j<N; j++)
            {
                C=(A[i][1]&B[j][1]).count()+
                    (A[i][1]&B[j][2]).count()*2+(A[i][2]&B[j][1]).count()*2+
                    (A[i][2]&B[j][2]).count()*4;
                if(j==N-1) printf("%d",C%3);
                else printf("%d
",C%3);
            }
    }
    return 0;
}
View Code

总结:

  bitset确实是位运算一大神器,能够在各种状态压缩中起到神奇的作用,但速度方面并不十分突出,上两题测试的时间相对偏长,不过一旦用上了,想必你离成功不远了。哈哈!!

  

原文地址:https://www.cnblogs.com/Mathics/p/3923557.html