第一种:直接暴力,在这就不说了
第二种:埃氏筛法(能处理1e6以下的数据)
首先,将2到n范围内的所有整数写下来。其中最小的素数为2,将表中所有2的倍数都划去。表中剩余的最小数字是3,不能被更小的数整除,所以也是素数,将表中所有3的倍数也划去。。。 依此类推,如果表中剩余的最小数字为m时,m就是素数,再将m的所有倍数划去。
代码如下:
int prime[100007], s = 0;
bool is_prime[1000007];
void init()
{
memset(is_prime,true,sizeof(is_prime));
for(int i=2; i<=1000000; ++i)
{
if(is_prime[i])
{
prime[s++] = i;
for(int j=i+i; j<=1000000; j+=i)
is_prime[j] = false;
}
}
}
第三种:区间筛选(能处理类似[a,b)区间中的素数,[a,b)区间:a<b<=1e12 , b - a <= 1e6)
一个数x的最小素因数一定不超过x^(1/2),那么有x^(1/2)以内的素数表,那么就可以运用埃氏筛法筛选[a,b)中的素数了;
memset(is_prime,true,sizeof(is_prime));
for(int i=0; (__int64)prime[i]*prime[i]<b; i++)
for(__int64 j=max((__int64)2, (a+prime[i]-1)/prime[i]) * prime[i]; j<b; j += prime[i])//其中prime数组是用埃氏提前预处理好的
is_prime[j-a] = false;
其中is_prime数组中[0,b-a)分别对应区间[a,b)