小鸡有一个由整数组成的数组,小鸡可以对这个数组进行任意次(可以不进行)全数组每个数加一或全数组每个数减一的操作。
现在,小鸡想让你回答 Q 次询问,每次询问给出一个整数 M,你需要回答任意次(可以不操作)操作后是否可以使得给定数组的乘积等于给出的整数 M。
输入
第一行输入两个正整数 n,Q (2 ≤ n ≤ 1e5 ,1 ≤ Q ≤ 5e5 ),表示数组长度与询问次数。
第二行输入n个空格分隔的整数 ai (−1e9 ≤ ai ≤ 1e9 ),表示数组中的元素。
接下来Q个空格分隔的整数M(−1e9 ≤ M ≤ 1e9 ),表示询问的数字。
输出
对于每个 M,请你输出一行"Yes"或"No"(不含引号)表示是否可以令全数组的乘积等于给定 M。
Input
4 9
1 -1 3 5
-75 19305 123 1 0 15 -15 1919810 114514
Output
No
Yes
No
No
Yes
No
Yes
No
No
解析:
把 1e9 分解成若干个不同的数的乘积,个数不大于20个;
把所有可能出现的数先存进 set 里,即可。
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
#define int long long
#define endl '\n'
#define ios ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int gcd(int a,int b) { return b? gcd(b,a%b) : a; }
typedef pair<int,int> PII;
const double PI=acos(-1.0);
const int N=2e6+10;
int n,q;
map <int,int> cnt;
vector <PII> a;
set <int> s;
void solve()
{
cin>>n>>q;
for (int i=1;i<=n;i++)
{
int x;
cin>>x;
cnt[x]++;
}
for (auto x:cnt) a.push_back(x);
s.insert(0);
if (a.size()<=20)
{
int M=1e5;
for (int k=0;k<a.size();k++)
{
for (int i=-M;i<=M;i++)
{
int now=1;
int cur=i-a[k].first; //记录操作步数 cur
for (auto [x,y]:a) //对可能出现的值进行运算
{
int v=x+cur;
if (v==0)
{
now=0; //修改处
break;
}
for (int j=1;j<=y;j++)
{
now=now*v;
if (abs(now)>1e9) break;
}
if (abs(now)>1e9) break;
}
if (abs(now)<=1e9) s.insert(now); //可能出现的值 now
}
}
}
while (q--)
{
int x;
cin>>x;
if (s.count(x)!=0) cout<<"Yes\n";
else cout<<"No\n";
}
}
signed main()
{
ios;
int T=1;
//cin>>T;
while (T--) solve();
return 0;
}