线性筛

线性筛:在\(O\left ( n\right )\)时间复杂度内筛出某东西

任意积性函数都可以线性筛

下面以线性筛素数说明为什么是线性的:

 1 void make_prime()
 2 {
 3     memset(prime,true,sizeof(prime));
 4     prime[0]=prime[1]=false;
 5     for(register int i=2; i<=maxn; i++)
 6     {
 7         if( prime[i]) Prime[num++]=i;
 8         for(register int j=0; j<num&&i*Prime[j]<maxn; j++)
 9         {
10             prime[i*Prime[j]] = false;
11             if( !(i%Prime[j]) ) break;
12         }
13     }
14     return ;
15 }

分析(核心):算法的关键之处在于break语句,break是为了保证任何一个合数都是被它的最小质因子筛掉的,所以能够保证每个数都自会被访问一次,这也就保证了复杂度是线性的

解释:根据唯一分解定理:任意一个数\(n\)都可以分解成:\(n=p_{1}^{t_{1}}p_{2}^{t_{2}}p_{3}^{t_{3}}\cdots p_{k}^{t_{k}}\)

所以我们要筛掉\(n\)的话,肯定是用 \(p_{1}\)去筛。

如果出现了 \(\left ( i\ mod\ Prime\left [ j\right ]\right )==0\)  则说明  \(Prime\left [ j\right ]是i的质因子\) ,那么此时如果我们继续用  \(i*Prime\left [ j+1\right ]\)  去筛某个数 \(x\) 的话,我们就是用  \(Prime\left [ j+1\right ]\)  去筛的 \(x\),可是很显然  \(Prime\left [ j\right ]\)  是\(x\)的一个质因子,并且  \(Prime\left [ j\right ]\)  比  \(Prime\left [ j+1\right ]\)  小,所以  \(Prime\left [ j+1\right ]\)  不是 \(x\) 的最小质因子,于是break,也就保证了每个数是被它的最小质因子筛掉的。

posted @ 2020-04-26 10:57  swsyya  阅读(140)  评论(0编辑  收藏  举报

回到顶部