题目大意:
题目链接:https://jzoj.net/senior/#main/show/3188
找出第
N
N
N个最小素因子是
P
P
P的正整数。
思路:
sto XXY orz \color{red}\texttt{sto\ XXY\ orz} sto XXY orz
sto XXY orz \color{blue}\texttt{sto\ XXY\ orz} sto XXY orz
sto XXY orz \color{green}\texttt{sto\ XXY\ orz} sto XXY orz
sto XXY orz(再加一遍XD) \color{white}\texttt{sto\ XXY\ orz(再加一遍XD)} sto XXY orz(再加一遍XD)
重要的事情说三遍。
这道题
n
≤
1
0
9
n\leq 10^9
n≤109。
XXY
d
a
l
a
o
dalao
dalao给出了
1
10
\frac{1}{10}
101常数的暴力。
然后就过了。
首先特判
n
=
1
n=1
n=1,显然输出1。
然后特判
n
>
1
n>1
n>1且
p
2
>
1
0
9
p^2>10^9
p2>109,显然输出0。
接下来依次特判
p
=
2
,
p
=
3
,
p
=
5
,
p
=
7
,
p
=
11
p=2,p=3,p=5,p=7,p=11
p=2,p=3,p=5,p=7,p=11。最坏情况下
p
=
5
p=5
p=5是
1
0
9
2
p
\frac{10^9}{2p}
2p109的复杂度。
然后剩下的就是
p
>
11
p>11
p>11的了。枚举
p
p
p的倍数,判断是否成立。
时间复杂度
O
(
1
0
8
+
O(10^8+
O(108+某些常数
)
)
)。鉴于JZOJ评测机很好,
416
m
s
416ms
416ms跑过了。
代码:
#include <cstdio>
#define rr register
using namespace std;
typedef long long ll;
const int MAXN=1e9;
const int Psum=35000;
int n,p,cnt,k,prime[Psum],v[Psum];
void find(int maxn)
{
for (int i=2;i<=maxn;i++)
{
if (!v[i])
{
v[i]=i;
prime[++cnt]=i;
}
for (int j=1;j<=cnt;j++)
{
if (prime[j]*i>maxn) break;
if (prime[j]>v[i]) break;
v[i*prime[j]]=prime[j];
}
}
}
int check(int x)
{
for (int i=1;i<k;i++)
if (!(x%prime[i])) return 0;
return 1;
}
int main()
{
scanf("%d%d",&n,&p);
if (n==1)
{
printf("%d",p);
return 0;
}
if (n>1&&(ll)p*(ll)p>MAXN)
{
printf("0");
return 0;
}
if (p==2)
{
if (n*p<=MAXN) printf("%d",n*p);
else printf("0");
return 0;
}
if (p==3)
{
ll x=3+(ll)(n-1)*6;
if (x<=MAXN) printf("%lld",x);
else printf("0");
return 0;
}
if (p==5)
{
for (rr int i=p;i<=MAXN;i+=2*p)
if (i%3)
{
n--;
if (!n)
{
printf("%d",i);
return 0;
}
}
printf("0");
return 0;
}
if (p==7)
{
for (rr int i=p;i<=MAXN;i+=2*p)
if (i%3&&i%5)
{
n--;
if (!n)
{
printf("%d",i);
return 0;
}
}
printf("0");
return 0;
}
if (p==11)
{
for (rr int i=p;i<=MAXN;i+=2*p)
if (i%3&&i%5&&i%7)
{
n--;
if (!n)
{
printf("%d",i);
return 0;
}
}
printf("0");
return 0;
}
find(Psum);
for (k=1;k<=cnt;k++)
if (prime[k]==p) break;
for (rr int i=p;i<=MAXN;i+=2*p)
if (check(i))
{
n--;
if (!n)
{
printf("%d",i);
return 0;
}
}
printf("0");
return 0;
}