可持久化可并堆+DP:http://blog.csdn.net/liuguangzhe1999/article/details/51132255
我也不想这个有趣的方法就这么绝迹了呢 但是我不会打
堆:http://blog.csdn.net/dropd/article/details/51138254
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(ll &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
namespace hash_map{
struct node{
ll x; int next;
}G[1000005];
int head[10000007],P=10000007,inum;
inline void add(ll x){
G[++inum].x=x; G[inum].next=head[x%P]; head[x%P]=inum;
}
inline int find(ll x){
for (int p=head[x%P];p;p=G[p].next)
if (G[p].x==x)
return p;
return 0;
}
}
const ll prime[]={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};
const int pnum=31;
struct data{
ll num;
int a[32];
}A[1000005];
int cnt;
ll N,K;
priority_queue<ll> Q;
int main()
{
ll itmp,ans,pos;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(N); read(K);
for (int i=1;i<=pnum && prime[i]<=N;i++)
{
itmp=prime[i];
for (int j=1;itmp<=N && itmp>0;j++,itmp*=prime[i])
{
hash_map::add(itmp);
A[++cnt].num=itmp; A[cnt].a[i]=j;
Q.push(itmp);
}
}
while (K--)
{
ans=Q.top(); Q.pop();
if (!K) break;
pos=hash_map::find(ans);
for(int i=2;i<=pnum;i++)
if(A[pos].a[i])
{
itmp=ans/prime[i]*prime[i-1];
if(!hash_map::find(itmp))
{
Q.push(itmp);
hash_map::add(itmp);
A[++cnt].num=itmp;
for(int j=1;j<=pnum;j++)
A[cnt].a[j]=A[pos].a[j];
A[cnt].a[i]--;
A[cnt].a[i-1]++;
}
}
}
printf("%lld\n",ans);
}