素数筛法
求1和n之间的所有素数
1. 朴素方法
int m = sqrt(n + 0.5);
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= m; i++) if(!vis[i])
for(int j = i * i; j <= n; j += i) vis[j] = 1;
\(vis[i]\)表示\(i\)是否不是素数。
时间复杂度\(\sum_{i=2}^{\sqrt{n}} \frac{n}{i} = O(nlogn)\)。
2. 线性筛
int pri[N], tot, np[N];
void sieve()
{
np[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!np[i]) pri[++tot] = i;
for (int j = 1; j <= tot && i * pri[j] <= n; j++)
{
np[i * pri[j]] = 1;
if (i % pri[j] == 0) break;
}
}
}
\(pri[i]\)表示第\(i\)个素数,\(np[i]\)表示\(i\)是否不是素数。
每次对数组np的赋值满足\(i\)是\(i*pri[j]\)中的最小质因子,所以赋值不会重复。时间复杂度为\(O(n)\)。

浙公网安备 33010602011771号