bitset大法吼啊
不难发现,如果询问的数的某一位为1,那么要找的数中的这一位也必须为1。所以要找的数中,每一个询问数中这一位为1的位都为1。
每一位开一个bitset,存有哪些数这一位为1。举个例子,对于样例 3 7 ,每一位的bitset应该长这样(最低位是第0位):
bit[0]:11 bit[1]:11 bit[2]:01 bit[3]:00
询问时,将询问数中为1的位的bitset与起来,得到的bitset中存的数,满足这些位上均为1。那么只需要判断得到的bitset中是否为空即可。
例如,询问 4 ,4 的二进制表达是 100 ,取第2位的bitset,这个bitset的第2位为1,即第2个数 7 与 4 等于 4 ,输出 yes 。
询问 9 ,二进制表达是 1001 ,将第0位和第3位的bitset与起来得到 00 ,输出 no 。
Code:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <bitset>
#define Rint register int
#define INF 0x3f3f3f3f
using namespace std;
typedef long long lxl;
const int maxn=1e5+5;
template <typename T>
inline void read(T &x)
{
x=0;T f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
x*=f;
}
int n,m;
bitset<maxn> bit[21],ans;
int main()
{
read(n),read(m);
for(int i=1,x;i<=n;++i)
{
read(x);
for(int j=0;j<=20;++j)
if(x&(1<<j))
bit[j].set(i);
}
int x;
while(m--)
{
read(x);
ans.set();
for(int i=0;i<=20;++i)
if(x&(1<<i)) ans=ans&bit[i];
puts(ans.any()?"yes":"no");
}
return 0;
} 
京公网安备 11010502036488号