代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll prime[1110000],pr=0;
bool v[19100000];
void getprime()
{
memset(v,true,sizeof(v));
for(int i=2;i<=16000000;i++)
{
if(v[i])prime[++pr]=i;
for(int j=1;j<=pr&&i*prime[j]<16000000;j++)
{
v[i*prime[j]]=false;
if(i%prime[j]==0)break;
}
}
}
int main()
{
getprime();
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
printf("%lld\n",prime[x]);
}
return 0;
}
作为拥有
O
(
n
)
O(n)
O(n) I’m faster than you的算法,它有很多细节.
比如:if(i%prime[j]==0)break;
这句话让每个数只筛了一次
证明:
设
i
=
p
1
c
1
p
2
c
2
.
.
.
.
.
.
p
m
c
m
,
i
∗
p
1
会
在
p
1
时
标
记
,
b
r
e
a
k
设i=p_1^{c_1}p_2^{c_2}......p_m^{c_m},i*p_1会在p_1时标记,break
设i=p1c1p2c2......pmcm,i∗p1会在p1时标记,break
∴
对
于
每
个
合
数
i
∗
p
只
会
被
它
的
最
小
质
因
子
p
筛
一
次
,
时
间
复
杂
度
为
O
(
N
)
\therefore对于每个合数i*p只会被它的最小质因子p筛一次,时间复杂度为O(N)
∴对于每个合数i∗p只会被它的最小质因子p筛一次,时间复杂度为O(N)。