题意:是否存在一个子集使得子集中所有元素的为 有一个需要注意的事情是:如果给定是2,那么那个子集中的所有数都应该是2的倍数,有了这个思想,我们就可以利用调和级数On的遍历x取1~n时存在的gcd。
vis[i]:标记是否是给定的个数内,是为,否则为 res[i]:标记是否能由一个子集构造使得
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<iomanip>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue>
# include<map>
# include<string>
# include<cstring>
# define eps 1e-9
# define fi first
# define se second
# define ll long long
# define int ll
// cout<<fixed<<setprecision(n)
using namespace std;
typedef unsigned long long ull;
typedef pair<int,int > PII;
const int mod=1e9+7;
const int MAX=3e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846;
int T,n,m;
bool vis[MAX],res[MAX];
int a[MAX];
void solve(){
cin >> n >> m;
for(int i = 1 ; i <= n ; i ++ ) vis[i] = false , res[i] = false; //初始化
for(int i = 1 ; i <= n ; i ++ ){
int x;
cin >> x;
vis[x] = true; //存在x
}
for(int i = 1 ; i <= n ; i ++ ){
int g = 0;
for(int j = i ; j <= n ; j += i) //gcd=i,构造的集合一定是i的倍数
if(vis[j]) g = __gcd(g,j); //输入的数据存在j,就求gcd
if(g == i) res[i] = true; //如果能构造出来i,res[i]就为true
}
while(m--){
int x;
cin >> x;
if(res[x]) cout<<"YES\n";
else cout<<"NO\n";
}
}
signed main(){
std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> T;
while(T--){
solve();
}
return 0;
}
/*
2 2 6 6 2 1 5
vis 1 2 3 4 5 6
i 1 ~ 7
j i ~ 7
i = 1
j: 1~7
*/