题目链接
这个题考虑逆向思维,要求你给出是不是存在包含x的数,可以直接先预处理出来给定序列的数包含的所有数。
从大到小枚举,如果这个数是序列中的数,那么考虑它的所有是1的位置,如果某个位置是1,那么减去2相应的次幂之后的数必定是这个数所包含的数。因为每次得到的包含的数一定是越来越小,所以一定每个数都能遍历到。当遍历到这个数包含的数之后,在对这个数的每一位进行检查,那么然后再对它是1的位置做相应的减法之后得到的数实际上就是原始的数减去某两个或者多个位置上2的次幂之后的数。因此一定能得到所有一个数包含的数。
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
ll q[200000];
ll dp[2000000];
int main()
{
ll n,m,x;
scanf("%lld%lld",&n,&m);
for(ll i=1;i<=n;i++)
{
scanf("%lld",&q[i]);
dp[q[i]]=1;
}
for(ll i=1000000;i>=0;i--)
{
for(ll j=0;j<=20;j++)
{
if(dp[i]&&(i&(1 << j)))
{
dp[i-(1<<j)]=1;
}
}
}
while(m--)
{
scanf("%lld",&x);
if(dp[x])
{
printf("yes\n");
}
else
{
printf("no\n");
}
}
return 0;
}