[CQOI2016]伪光滑数

伪光滑数

题解

延续了CQOI**的传统,不过现在是联考了。

很容易发现,这个数为a_{k}^{k}时是最大的,其他的不是全部公因子都为a_{k}的一定会比它小,毕竟a_{k}^{k}\leq n

所以我们可以先把所有为a_{i}^{i}的数给预处理出来,之后再一个个替换它的质因数,一直枚举到2即可。

源码

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL; 
#define int LL
#define gc() getchar()
template
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 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;
}

谢谢!!!

你可能感兴趣的:(------数论------,#,队列)