由于之前的洛谷月赛 20191109中我bitset不熟,直接导致了T3(70 sim 100pts ightarrow 50pts)。复习一下bitset。
一、概念
A bitset stores bits.
因此,bitset可以理解为一个bool数组,但是速度更快,可以直接像一个整数一样进行位运算,或者统计1的个数等。
二、声明与初始化
bitset声明,传入的变量n为bitset长度:
#include <bitset>
bitset <n> b; // 全为0
bitset <n> b(u); // 从unsigned long型变量u复制而来
bitset <n> b(s); // 从string对象s复制而来
bitset <n> b(s, pos, m); // 从string对象s的[pos, pos+m]复制而来
使用unsigned long初始化的几个例子:
bitset<16> bitvec1(0xffff); // bits 0 ... 15 are set to 1
// bitvec2 same size as initializer
bitset<32> bitvec2(0xffff); // bits 0 ... 15 are set to 1; 16 ... 31 are 0
// on a 32-bit machine, bits 0 to 31 initialized from 0xffff
bitset<128> bitvec3(0xffff); // bits 32 through 127 initialized to zero
使用unsigned long或者string初始化时,原始类型会被转换为位模式,以二进制形式对应bitset的初始位,超出指定bitset长度的部分舍弃。
三、操作
本节翻译自c++ reference。
1.访问
-
b[pos]:访问b的第pos位
-
b.count():统计1的个数
-
b.size():返回bitset位数
-
b.test(pos):返回b[pos]的值
-
b.any():检验是否有任何1
-
b.none():检验是否无任何1
-
b.all():检验是否均为1(c++ 11)
2.修改
- b.set(pos):将b[pos]修改为1
- 若不传入pos,将所有位修改为1
- b.reset(pos):将b[pos]修改为0
- 若不传入pos,将所有位修改为0
- b.flip(pos):将b[pos]取反
- 若不传入pos,将所有位逐位取反
3.转化
- b.to_string():转化为string
- b.to_ulong():转化为unsigned long
- b.to_ullong():转化为unsigned long long(c++ 11)
4.输出
- os << b:将b输出到os流
- 示例输出如下
bitset <16> b(0xff);
cout << b;
///////////////////////////////////////////////
//output:
//0000000011111111
///////////////////////////////////////////////
5.位操作
bitset支持位操作符,基本上可以看作一个整型来处理。
// bitset operators
#include <iostream> // std::cout
#include <string> // std::string
#include <bitset> // std::bitset
int main ()
{
std::bitset<4> foo (std::string("1001"));
std::bitset<4> bar (std::string("0011"));
std::cout << (foo^=bar) << '
'; // 1010 (XOR,assign)
std::cout << (foo&=bar) << '
'; // 0010 (AND,assign)
std::cout << (foo|=bar) << '
'; // 0011 (OR,assign)
std::cout << (foo<<=2) << '
'; // 1100 (SHL,assign)
std::cout << (foo>>=1) << '
'; // 0110 (SHR,assign)
std::cout << (~bar) << '
'; // 1100 (NOT)
std::cout << (bar<<1) << '
'; // 0110 (SHL)
std::cout << (bar>>1) << '
'; // 0001 (SHR)
std::cout << (foo==bar) << '
'; // false (0110==0011)
std::cout << (foo!=bar) << '
'; // true (0110!=0011)
std::cout << (foo&bar) << '
'; // 0010
std::cout << (foo|bar) << '
'; // 0111
std::cout << (foo^bar) << '
'; // 0101
return 0;
}
///////////////////////////////////////////////////////
//output:
//1010
//0010
//0011
//1100
//0110
//1100
//0110
//0001
//0
//1
//0010
//0111
//0101
///////////////////////////////////////////////////////