伪光滑数
题解
延续了CQOI**的传统,不过现在是联考了。
很容易发现,这个数为时是最大的,其他的不是全部公因子都为的一定会比它小,毕竟。
所以我们可以先把所有为的数给预处理出来,之后再一个个替换它的质因数,一直枚举到2即可。
源码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
#define int LL
#define gc() getchar()
template<typename _T>
inline void read(_T &x){
_T f=1;x=0;char s=gc();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
x*=f;
}
int n,k;
int zs[55]={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 ming{
int val,mp,mi,lim;
friend bool operator < (ming x,ming y){
return x.val<y.val;
}
};
priority_queue<ming> q;
signed main(){
read(n);read(k);
for(int i=1;i<=31;i++){
int now=zs[i];
for(int j=1;now<=n;j++,now=now*zs[i])
q.push((ming){now,zs[i],j,i-1});
}
while(k--){
ming now=q.top();q.pop();
if(!k)return !(printf("%lld",now.val));
if(now.mi>1)
for(int i=1;i<=now.lim;i++)
q.push((ming){now.val/now.mp*zs[i],now.mp,now.mi-1,i});
}
return 0;
}