堆,贪心
k比较小,我们可以用一个堆维护,不断更新更大值
发现最大的伪光滑数的所有质因数相同(把一个合法的伪光滑数小的质因数全部换成最大的也满足式子,质因数个数,最大质因数,N均无变化)
堆维护,每次取出最大值,若最大质因数幂次大于1,就把其中一个最大质因数换成较小,再扔进堆里,这样枚举没有遗漏和重复。
当我们取出第k次是即是答案
时间复杂度(O(klog_k))
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
int n,k,pri[32]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127};
struct node{
int v,p,mi,lim;
inline bool operator <(const node &a)const{
return v<a.v;
}
};
priority_queue<node>q;
signed main(){
n=read();k=read();
for(int i=1;i<=31;i++)
for(int j=1,x=pri[i];x<=n;j++,x=x*pri[i])
q.push((node){x,pri[i],j,i-1});
while(k--){
node x=q.top();q.pop();
if(!k){cout<<x.v;return (0-0);}
if(x.mi>1)for(int i=1;i<=x.lim;i++)
q.push((node){x.v/x.p*pri[i],x.p,x.mi-1,i});
}
return (0-0);
}