版权声明:欢迎dalao指出错误暴踩本SD,蒟蒻写的博客转载也要吱一声 https://blog.csdn.net/enjoy_pascal/article/details/89006067
description
找出第N个最小素因子是P的正整数。
analysis
-
首先要知道大于 的 第二个就不成立了,范围缩小了很多
-
设第 个满足条件的数是 ,这个可以分类讨论一下
-
当 比较大时,线筛出 的数的最小质因数,然后扫一遍乘个 判断可以知道答案
-
当 比较小时,需要知道一个东西
不想打字
-
后面 那个其实是容斥,就是奇数个的答案都减去偶数个的答案
实现这个用暴力 -
就二分 ,容斥
加暴力求出 最小质因子的个数,然后就可以了 -
根据数据可以发现 左右分类较优
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 15000005
#define MAXM 1000000
#define INF 1000000000
#define ll int
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))
using namespace std;
ll prime[MAXM],s[MAXN];
ll n,p,tot,k;
O3 inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
O3 inline void init()
{
fo(i,2,MAXN-1)
{
if (!s[i])prime[++tot]=i,s[i]=i;
for (reg j=1;j<=tot && prime[j]*i<MAXN;++j)
{
s[prime[j]*i]=prime[j];
if (i%prime[j]==0)break;
}
}
}
O3 inline ll judge(ll x)
{
ll ans=0;
fo(i,0,k-1)
{
long long temp=1ll;int cnt=0;
for (reg tot=i,j=1;tot;tot/=2,++j)
{
if (tot&1)temp*=prime[j],++cnt;
}
ans+=(cnt&1?-1:1)*(x/temp);
}
return ans;
}
O3 int main()
{
//freopen("T2.in","r",stdin);
n=read(),p=read(),init();
if (p>=50)
{
ll i=1;--n;
while (i<=INF/p && n)
{
if (s[i]>=p)
{
--n;if (!n)break;
}
++i;
}
printf("%d\n",!n?i*p:0ll);
return 0;
}
tot=0;while (prime[tot+1]<p)++tot;
k=1<<tot;
ll l=0,r=INF/p,ans=0;
while (l<=r)
{
ll mid=(l+r)>>1;
judge(mid)>=n?ans=mid,r=mid-1:l=mid+1;
}
printf("%d\n",ans*p);
return 0;
}