看到题目的数据,我首先想到了状压dp但是这道题并没有那么复杂
假设我们加入一个数字7(111), 包含的数字有110,011,101,100.....显然这些答案都小于原数字,这就是无后向性。
但是如果将每一个数字所包含的所有数字都进行标记,会有很多重复转移(111会标记011和001,而011又会标记001,显然重复)
我们从大到小枚举每个数字,如果该数字已经被包含,则枚举删除二进制中的一个1,删除后将其标记,这样就删除了无用转移。(因为每一次只会标记二进制中1比原数字少1个的状态)
最多有10^6个状态,每次转移最多需要20次(因为二进制最多有20个1)故复杂度为O(能过)O(10^7)
int main(){ n=read(), m=read(); for(int i=0; i<n; i++) a[read()]=1; for(int i=1000005; i>0; i--) if(a[i]) for(int j=0; (1<<j)<=i; j++) if(((1<<j)&i)) a[i-(1<<j)] = 1; while(m--) printf("%s\n", a[read()]?"yes":"no"); return 0; }