求最小质因子等于 的第 小的正整数。 一定是质数。若答案超过 则输出 。( )
论文题。
《2014信息学奥林匹克中国国家队候选队员论文——寻找k优解的几种方法》,俞鼎力。
#include <cstdio>
#include <cstring>
#define R register
int P[966218], tot, n, p, vis[14925393], cnt;
namespace Part1
{
int pos, cnt;
void main()
{
R int lim = 1e9 / p;
for(R int i = 2; i <= lim; ++i)
{
if(!vis[i])
{
P[++tot] = i;
vis[i] = i;
}
for(R int j = 1; P[j] * i <= lim; ++j)
{
vis[i * P[j]] = P[j];
if(i % P[j] == 0) break;
}
}
--n;
if(n == 0){ printf("%d\n", p); return ; }
for(R int i = 2; i <= lim; ++i)
if(vis[i] >= p && !--n){ printf("%d\n", i * p); return ; }
puts("0");
}
}
namespace Part2
{
int f[1 << 17];
void main()
{
for(R int i = 2; i < p; ++i)
{
if(!vis[i]) P[tot++] = i;
for(R int j = 0; P[j] * i < p; ++j)
{
vis[i * P[j]] = 1;
if(i % P[j] == 0) break;
}
}
R int Full = 1 << tot;
for(R int i = 0; i < Full; ++i)
{
f[i] = p;
R bool flag = 0;
for(R int j = 0; j < tot; ++j) if(i >> j & 1) flag ^= 1;
for(R int j = 0; j < tot; ++j) if(i >> j & 1)
{
if(1ll * f[i] * P[j] > 1000000000)
{
f[i] = 2147483647;
break;
}
f[i] *= P[j];
}
if(flag) f[i] = -f[i];
}
R int l = -10, r = 1e9 + 10;
while(r - l > 1)
{
R int mid = l + r >> 1;
R long long Ans = 0;
for(R int i = 0; i < Full; ++i) Ans += mid / f[i];
if(Ans >= n) r = mid;
else l = mid;
}
if(r > 1e9) puts("0");
else printf("%d\n", r);
}
}
int main()
{
scanf("%d %d", &n, &p);
if(p >= 67) Part1::main();
else Part2::main();
return 0;
}