Description
除去对铁质盔甲强烈的热爱,Brunhilda是一个正常的7岁女孩。近期,她正在策划一个完美的生日派对。她发明了如下的一个游戏:所有的孩子在一个数k被宣读之前不停地跑来跑去。当这个数字k宣读后,所有的孩子将形成人数恰好为k的若干群体,且保证剩余的孩子数目小于k。最后,这不足k个的孩子将从游戏中被淘汰。紧接着,比赛将继续进行,并公布一个新的数字k。游戏将在所有的孩子都被淘汰后结束。
Brunhilda请她的父亲Wotan在游戏中来宣读数字。Wotan不喜欢这个游戏,当然也不希望在游戏的第一轮就宣布一个正无穷(PS:宣布正无穷等于将所有的孩子都从游戏中淘汰)。 Brunhilda认为这在派对上是相当尴尬的情形,所以她给了她父亲一串共计m个素数的列表。这样,她的父亲便可以从中进行选择。当然,相同的数字在游戏中可以被多次宣读。
Wotan想尽快结束比赛,因为他有一张他最喜欢的足球俱乐部 FC Asgard的比赛门票。不幸的是,Brunhilda不知道派对上参加游戏的孩子数目。现在,对于Q个不同的数n1,...,nQ个儿童,Wotan要预先知道他所需宣读的最少数字,以便他尽早结束游戏。
Brunhilda请她的父亲Wotan在游戏中来宣读数字。Wotan不喜欢这个游戏,当然也不希望在游戏的第一轮就宣布一个正无穷(PS:宣布正无穷等于将所有的孩子都从游戏中淘汰)。 Brunhilda认为这在派对上是相当尴尬的情形,所以她给了她父亲一串共计m个素数的列表。这样,她的父亲便可以从中进行选择。当然,相同的数字在游戏中可以被多次宣读。
Wotan想尽快结束比赛,因为他有一张他最喜欢的足球俱乐部 FC Asgard的比赛门票。不幸的是,Brunhilda不知道派对上参加游戏的孩子数目。现在,对于Q个不同的数n1,...,nQ个儿童,Wotan要预先知道他所需宣读的最少数字,以便他尽早结束游戏。
Input
第一行包含整数m和Q。
第二行包含m个不同的递增素数pi(1≤i≤M),表示Wotan可以宣读的数字。
接下来Q行分别包含一个整数nj(1≤j≤Q),表示可能参加游戏的孩子数目nj。
第二行包含m个不同的递增素数pi(1≤i≤M),表示Wotan可以宣读的数字。
接下来Q行分别包含一个整数nj(1≤j≤Q),表示可能参加游戏的孩子数目nj。
Output
输出包括Q行。第j行表示对于询问nj所得到的答案,即如果Wotan能结束游戏,请输出他最少所需要宣读的数字个数,否则输出字符串oo(两个小写字母o表示∞)。
Sample Input
2 2
2 3
5
6
Sample Output
3
oo
Data Constraint
20%的数据:m,nj,Q<=10000.
另有20%的数据:Q=1
100%的数据:1<=m,Q<=100 000,1<=nj<=10 000 000,2<=pi<=10 000 000
另有20%的数据:Q=1
100%的数据:1<=m,Q<=100 000,1<=nj<=10 000 000,2<=pi<=10 000 000
分析
不难发现,当一个数在[x,x+prime[i])(x|prime[i])中时,它可以由x转移过来
那我们考虑贪心,对于这个x|prime[i],我们记录最大的可被x整除的prime,然后用两个端点跳来跳去,因为越前面转移过来的越优
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; const int N=1e7+100; int m,q; int p[N/100],mx[N],f[N]; void Prime() { for (int i=1;i<=m;i++) for (int j=1;j<=(N-100)/p[i];j++) mx[j*p[i]]=p[i]; } int main() { scanf("%d%d",&m,&q); for (int i=1;i<=m;i++) scanf("%d",&p[i]); Prime();mx[0]=p[m]; for (int l=0,r=1;l<r&&r<=N-100;l++) { if (!mx[l]) continue; for (;r<=min(l+mx[l]-1,N-100);) f[r++]=f[l]+1; } for (;q;q--) { int qq; scanf("%d",&qq); printf((f[qq]?"%d\n":"oo\n"),f[qq]); } }