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\n");
        else
            printf("No\n");
    }
    return 0;
}

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\n",C%3);
            }
    }
    return 0;
}

总结:

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

  

Bitset小结 (POJ2443 & HDU4920),布布扣,bubuko.com

时间: 2024-09-30 18:10:40

Bitset小结 (POJ2443 & HDU4920)的相关文章

ACM模板——bitset小结

对于一个叫做a的bitset: a.size() 返回大小(位数) a.count() 返回1的个数 a.any() 返回是否有1 a.none() 返回是否没有1 a.set() 全都变成1 a.set(p) 将第p+1位变成1 a.set(p, x) 将第p+1位变成x a.reset() 全都变成0 a.reset(p) 将第p+1位变成0 a.flip() 全都取反 a.flip(p) 将第p+1位取反 a.to_ulong() 返回它转换为unsigned long的结果,如果超出范围

[POJ2443]Set Operation(bitset)

传送门 题意:给出n个集合(n<=1000),每个集合中最多有10000个数,每个数的范围为1~10000,给出q次询问(q<=200000),每次给出两个数u,v判断是否有一个集合中同时含有u,v两个数 枚举每一个集合,看看是否同时又u和v,显然超时 用bitset维护每一个数所在集合,求解的时候直接即可u & v #include <cstdio> #include <bitset> using namespace std; int n, m; bitset

【bitset】hdu4920 Matrix multiplication

先把两个矩阵全都mod3. S[i][j][k]表示第i(0/1)个矩阵的行/列的第k位是不是j(1/2). 然后如果某两个矩乘对应位上为1.1,乘出来是1: 1.2:2: 2.1:2: 2.2:1. 然后分这四种情况把bitset and 起来,然后用count()数一下个数,计算下对答案矩阵该位置的贡献即可. #include<cstdio> #include<bitset> using namespace std; #define N 801 int n,x; bitset&

POJ2443 Set Operation (基础bitset应用,求交集)

You are given N sets, the i-th set (represent by S(i)) have C(i) element (Here "set" isn't entirely the same as the "set" defined in mathematics, and a set may contain two same element). Every element in a set is represented by a posit

C++ 之 bitset

在PC端文件播放器中,多画面管理时,将整个画面切割成N个矩形块.将打开显示与否的信息放在bitset容器中,今天就来对bitset做个小结 1.bitset可以表示二进制的有序集,用bitset来处理程序中的需要保存一组标志的操作很简便,下面总结一下bitset的一些函数. 2.定义和初始化bitset: 定义一个bitset时需要声明它包含多少个二进制位,大小必须是一个常量表达式,bitset中的二进制位是未命名的,可以通过位置来访问.编号从右到左依次从0位开始,从低到高. 例:bitset<

把《c++ primer》读薄(3-3 标准库bitset类型)

督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. //开头 #include <bitset> using std::bitset; 问题1.标准库bitset类型(模版) 需要处理二进制位的时候,可以使用c++标准库提供的bitset类型,它也是类模版,类似vectro容器,唯一不同的是,bitset类型需要说明长度,使用常量表达式给出的整型字面值或者已经初始化的cosnt对象. bitset<32> bit;//从0到31位算的,bit的32位每位初始化为

【C++ Primer每日一刷之五】标准库类型小结

标准库类型小结 C++ 标准库定义了几种更高级的抽象数据类型,包括 string 和 vector 类型.string 类型提供了变长的字符串,而 vector 类型则可用于管理同一类型 的对象集合.迭代器实现了对存储于容器中对象的间接访问.迭代器可以用于访问和遍历 string 类型和vectors 类型的元素.下一节将介绍 C++ 的内置数据类型:数组和指针.这两种类型提供了类似于 vector 和 string 标准库类型的低级抽象类型.总的来说,相对于C++ 内置数据类型的数组和指针而言

2-SAT 问题与解法小结

2-SAT 问题与解法小结 这个算法十分的奇妙qwq... 将一类判定问题转换为图论问题,然后就很容易解决了. 本文有一些地方摘录了一下赵爽<2-SAT解法浅析> (侵删) 一些概念: \(SAT\)问题:就是给一些布尔变量赋值,使得所有给你的条件成立的问题---适定性(Satisfiability)问题.我们令\(k\)为所有条件中含有变量的最大值,那么我们就可以称其为\(k-SAT\)问题. 可以证明\(k>2\)时候为NP完全问题,而\(k=2\)的时候存在多项式解法. \(2-S

使用Apache POI导出Excel小结--导出XLS格式文档

使用Apache POI导出Excel小结 关于使用Apache POI导出Excel我大概会分三篇文章去写 使用Apache POI导出Excel小结--导出XLS格式文档 使用Apache POI导出Excel小结--导出XLSX格式文档 使用Apache POI导出Excel--大数量导出 导出XLS格式文档 做企业应用项目难免会有数据导出到Excel的需求,最近在使用其,并对导出Excel封装成工具类开放出来供大家参考.关于Apache POI Excel基本的概念与操作我在这里就不啰嗦