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中是否为空即可。

例如,询问 44 的二进制表达是 100 ,取第2位的bitset,这个bitset的第2位为1,即第2个数 74 等于 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;
}