【OI】【奇技淫巧】bitset在OI中的应用

【OI】【奇技淫巧】bitset在OI中的应用

萌萌哒喵酱萌萌哒喵酱

震惊,GDKOI2018D1T3竟有bitset水法!

作为一只标准蒟蒻,我在学不会标准正解FFT的情况下然后去学了一下bitset。。。

一般你翻开一个关于介绍bitset的blog,基本画风是这样的:

(来源:cnblogs.com/BaiYiShaoNi

然而作为菜鸡的我一看完就有点懵,不是说bitset可以快速查找某一个元素喵,这些...都是处理二进制的呀。

然后经过我的几次无脑实验我大概就摸清了使用bitset的基本套路:

1、bitset其实是可以看做是一个bool类型的数组,只不过bitset的一个元素只占1bit的空间,而bool里面则是占1byte,这样就相当于同时减少了时间复杂度和空间复杂度,这也是bitset的优势所在。

2、使用bitset的时候你需要先声明,类似声明vector一样,基本格式:

#include<bitset>
bitset<10005>a;  //10005是bitset的大小,相当于数组大小,a就相当于一个bool数组。


3、前面说了bitset是基本和bool数组的用法一样的,所以其实赋值的时候完全可以这样写

a[0]=1;//等价于写a.set(0);


4、那么话说回来如何快速查找一个元素是否在集合内呢,你大可这样写:

//x为查找元素:
if (f[x]) printf("Yes\n"); else printf("No\n");

有人可能会问了,那这不是bool数组也可以做到吗,其实还是空间的问题,用bitset可以轻松存10^8个数字并查询,bool空间是它的八倍然后就极有可能MLE~

那我们就来一道水题练练手吧

2443 -- Set Operationpoj.org

果然很水对吧(

#include<cstdio>
#include<algorithm>
#include<bitset>
using namespace std;
int n,i,j,k,q,x,g,y;
bool fl;
bitset<10005> a[1015];
int main()
{
	scanf("%d",&n);
	for (i=1;i<=n;i++)
	{
		scanf("%d",&x);
		for (j=1;j<=x;j++)
		{
			scanf("%d",&g);
			a[i][g]=1;
		}
	}
	scanf("%d",&q);
	for (i=1;i<=q;i++)
	{
		scanf("%d%d",&x,&y);
		fl=1;
		for (j=1;j<=n;j++)
			if (a[j][x]&&a[j][y]) {printf("Yes\n");fl=0;break;}
		if (fl) printf("No\n");
	}
	return 0;
}

Q:有没有好玩一点的题

A:bzoj3687把dp和bitset结合了起来,可惜是一道权限题qwq。有兴趣的可以看hzwer的blog看一下这道题w(hzwer.com/3697.html

文章被以下专栏收录
5 条评论