Prime Gift
阿新 • • 發佈:2018-11-01
題目描述
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; }