bitset类:
------ 用于处理二进制位的有序集,每个位都是0或1两种状态,占1bit
主要作用:
①用于保存任意二进制数(可以远超64位),支持修改统计翻转等
②通过bitset二进制表示状态,例如图的联通等
③常数优化,存储优化调用头文件:
#include<bitset>
using namespace std;
详细用法(部分):
1、初始化:
bitset<n> b; ------ 定义一个长度为n的二进制数b
bitset<n> b(u); ------ 定义u是b的一个副本
bitset<n> b(str); ------ 用string对象初始化b,剩下空位补0,注意从string对象读入位集的顺序是从右向左!
bitset<n> b(str, i, n) ------ 用string对象初始化b,b是str中从下标i开始的n个位的副本,读入顺序如上
2、其它操作:
b.any() ------ b中存在为1的二进制位么?
b.none() ------ b中不存在为1的二进制位么?
b.count() ------ b中为1的二进制位个数
b[pos] ------ 访问b中在pos处的二进制位(pos从0开始)
b.size() ------ b中二进制位的个数
b.set() ------ 把b中所有二进制位全部置为1
b.reset() ------ 把b中所有二进制位全部置为0
b.flip() ------ 把b中所有二进制全部取反
例题:http://codeforces.com/gym/100342 J:Triatrip
题意:输入一个有向图的邻接矩阵,求有多少个三元环(A到B,B到C,C又回A)
题解:n^3暴力,枚举每个BC,看有多少个点A满足从A到B,从C到A,最后答案除以3即可
(每个三元环刚好被重复计算3次)
#include<stdio.h>
#include<bitset>
using namespace std;
bitset<1505> G[1505], F[1505], sum;
int main(void)
{
freopen("triatrip.in", "r", stdin);
freopen("triatrip.out", "w", stdout);
char ch;
int n, i, j;
long long ans;
scanf("%d", &n);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf(" %c", &ch);
if(ch=='+')
G[i][j] = F[j][i] = 1;
}
}
ans = 0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(G[i][j])
{
sum = G[j]&F[i];
ans += sum.count();
}
}
}
printf("%I64d\n", ans/3);
return 0;
}
/*
#include<stdio.h>
#include<iostream>
#include<string>
#include<bitset>
using namespace std;
int main(void)
{
int i;
string str("10110111011110101010");
bitset<20> b(str, 4, 12);
for(i=0;i<=11;i++)
cout<<b[i]; //用cout输出bitset集,输出结果010111101110
printf("\n");
printf("%d\n", b.count());
b.flip();
cout<<b<<endl; //输出结果11111111100010000101
return 0;
}*/