Bitset模板 Bitset题型大荟萃

以codeforces上的ASC28J为例,讲了一些我遇到的Bitset的题目及做法

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<functional>
#include<string>
#include<algorithm>
#include<time.h>
#include<bitset>
void fre(){freopen("triatrip.in","r",stdin);freopen("triatrip.out","w",stdout);}
template <class T> inline void scand(T &x){char c;x=0;while((c=getchar())<'0');while(c>='0'&&c<='9')x=x*10+(c-48),c=getchar();}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int N=1515,M=0,Z=1e9+7,maxint=2147483647,ms31=522133279,ms63=1061109567,ms127=2139062143;
int n,i,j;
char s[N];
/*
【算法介绍】
bitset是可以类似于状压DP,可以对01状态进行压缩和表示。
<1>bitset不仅限于32bits or 64bits,而是可以达到甚至是1e8 bits
<2>bitset支持or and xor << >> 等位运算,效率很高
其常用函数如下:
b.any()			判断b中是否存在值为1的二进制位
b.none()		判断b中是否不存在值为1的二进制位
b.count()		判断b中值为1的二进制位个数
b.size()		判断b中二进制位的个数
b[pos]			访问b中在pos处的二进制位
b.test(pos)		判断b中在pos处的二进制位是否为1
b.set()			把b中所有二进制位都置为1
b.set(pos)		把b[pos]置为1
b.reset()		把b中所有二进制位都置为0
b.reset(pos)	把b[pos]置为0
b.flip()		把b中所有二进制位逐位取反
b.flip(pos)		把b[pos]取反

scanf("%lld", &e); cout << e << endl;	//对bitset做读入或输出,输出的位置关系为高位 -> 低位
e[pos] = 1;  cout << e << endl;			//pos的位置关系在bitset上,相对位置关系为高位 -> 低位
使得e <<= 1相当于对于所有的x,都有e[x] = e[x - 1]

UI* v = (UI*)&T;		//把bitset转化为UI的数组

使用举例1	ASC28J:------------------------------------
http://codeforces.com/gym/100342/attachments/download/2145/20072008-winter-petrozavodsk-camp-andrew-stankevich-contest-28-asc-28-en.pdf
[题意]
给你一个可达1500大小的01矩阵,b[i][j]==1表示从i到j有边。
问你这个图中含有多少个三元环。
[分析]
最暴力的O(n^3)做法是——
for(i=0;i<n;i++)for(j=0;j<n;j++)for(k=0;k<n;k++)
	if(a[i][j]&&a[j][k]&&a[k][i])ans++;
但这个时间复杂度是O(n^3),于是想到用bitset优化
如果有(j->i)以及(i->k)边和(k->j)边,那么就构成了一个三元环。
于是for(i=0;i<n;i++)for(j=0;j<n;j++)if(out[j][i])
	ans+=(out[i]&in[j]).count();
(i->0)(i->1)(i->2)...(i->n)
(0->j)(1->j)(2->j)...(n->j)
两者&一下,然后再count()一下。就AC啦

使用举例2	TOJ4119:------------------------------------
1个bool是1字节,8个bitset单位才是1字节。
所以,用bool可以实现的,几乎都可以用bitset优化时间复杂度+空间复杂度

使用举例3	HDU5313 or GYM100781F ----------------------
注意,bitset可以说b[0]是最低位,
左移<<=会使得其变大
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值