线性筛法

在大多数数论的朴素筛法中,时间复杂度通常为O(nloglogn),尽管已经十分快了,但在有些情况下不适用。为此欧拉提出了一种筛法,能够在O(n)时间内求出1~n的所有素数,而且有很大拓展空间。

代码:

void get_prime(int n)
{
 memset(is_prime,true,sizeof(is_prime));

 size=0,is_prime[1]=0;

 rep(i,2,n)
 {
  if (is_prime[i]) prime[++size]=i;
  for (int j=1;(j<=size)&&(i*prime[j]<=n);j++)
  {
   is_prime[i*prime[j]]=false;
   if ((i%prime[j])==0) break;
  }
 }
}


该代码实现了在O(n)时间内求解1~n的所有素数,至于为什么是O(n),因为每一个合数只会被它的最小因子筛去。

拓展:

该代码还可用于求解某些积性函数,如欧拉函数,逆元函数等。

以欧拉函数为例:

void get_prime(int n)
{
 memset(is_prime,true,sizeof(is_prime));

 size=0;

 rep(i,2,n)
 {
  if (is_prime[i]) prime[++size]=i,phi[i]=i-1;
  for (int j=1;(j<=size)&&(i*prime[j]<=n);j++)
  {
   is_prime[i*prime[j]]=false;
   phi[i*prime[j]]=phi[i]*phi[prime[j]];
   if ((i%prime[j])==0)
   {
    phi[i*prime[j]]=phi[i]*prime[j];
    break;
   }
  }
 }
}
posted @ 2016-08-06 23:40  Krew  阅读(248)  评论(0)    收藏  举报