题目描述
Jyt有n个质数,分别为p1,p2,p3…,pn。
她认为一个数x是优秀的,当且仅当x的所有质因子都在这n个质数中。
她想知道第k大的优秀的数是多少。保证答案不超过10e18。
题解
首先我们发现,p越小搜索量越大,一半的时候刚刚好能过,那么我们思考一下折半乱搞,奇偶搜索,分别记两个数组。然后看到答案这么大考虑二分答案,每次双指针扫有几个够的,注意最后可能一个区间内的都有这么多个,满足的时候要往前挤
代码
#include <bits/stdc++.h>
#define maxn 2000005
#define INF 1e18
#define LL long long
#define U unsigned long long
using namespace std;
inline int read(){
int res,f=1; char c;
while(!isdigit(c=getchar())) if(c=='-') f=-1; res=(c^48);
while(isdigit(c=getchar())) res=(res<<3)+(res<<1)+(c^48);
return res;
}
int n,m,a[maxn],cnt1,cnt2;
LL num[maxn],NUM[maxn];
void dfs(int x,LL now){
num[++cnt1]=now;
for(int i=x;i<=n;i+=2){
if(now<=(long double)INF/a[i]) dfs(i,now*a[i]);
}
}
void DFS(int x,LL now){
NUM[++cnt2]=now;
for(int i=x;i<=n;i+=2){
if(now<=(long double)INF/a[i]) DFS(i,now*a[i]);
}
}
int check(LL lim){
LL tail=cnt2,sum=0;
for(int i=1;i<=cnt1;i++){
while(tail && NUM[tail]>(long double)lim/num[i]) tail--;
if(!tail) break;sum+=tail;
}
return sum;
}
int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
dfs(1,1);
DFS(2,1);
sort(num+1,num+cnt1+1);
sort(NUM+1,NUM+cnt2+1);
U l=1,r=INF,mid;
m=read();
while(l<r){
mid=l+r>>1;
if(check(mid)>=m) r=mid;
else l=mid+1;
}
cout<<l<<endl;
return 0;
}