埃拉托斯尼丝筛法:
先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。
long long Isprime()
{
long long k = 0;
prim[0] = prim[1] = 1;
memset(prim,0,sizeof(prim));
for(long long i = 2; i <= 47000; i++)
{
if(!prim[i])
{
p[k++] = i;
for(long long j = i*i; j <= 47000; j += i)
{
prim[j] = 1;
}
}
}
return k;
}
以上代码就是按照这个思路写的,这是一个完全正确的代码
long long Isprim(int n)
{
for(int i = 2; i <= sqrt(n); i++)
{
for(int j = 3; j <= n; j++)
{
if(j % i == 0)
p[j] = 1;
}
}
}
以前我还这样写,因为是筛法,假如1~n,最大的因子就是根号n,,从1~n,先删1的倍数,然后2的倍数....所以筛到根号n就可以了。这个方法有问题
还有也是按照上面写的但是判断2的倍数3的倍数是用了取余,这大大减慢了筛法的速度,导致了超时。其实可以直接加上它的倍数。
现在才真正理解筛法,先将2~n个数写到纸上,在2上面画一个圈,然后划去2的其他倍数,第一个既没有花圈有没被删除的数是3,将它花圈,在划去3的其他倍数,现在没有花圈有没删除的是5,5花圈.......而且他是算区间的素数,平时我们都用他求1~n,其实他还可以求a~b之类的素数