[线性筛][筛素数/筛约数个数]

Posted mekakucityactor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[线性筛][筛素数/筛约数个数]相关的知识,希望对你有一定的参考价值。

线性筛中每个数只会被最小的素因子筛一次

1)线性筛素数

 1 void getprime(int siz){
 2     memset(isprime,1,sizeof(isprime));
 3     isprime[1]=0;
 4     for(int i=2;i<=siz;i++){
 5         if(isprime[i])prime[++tot]=i;
 6         for(int j=1;j<=tot&&i*prime[j]<=siz;j++){
 7             isprime[i*prime[j]]=0;
 8             if(i%prime[j]==0)break;
 9         }
10     }
11 }

2)线性筛约数个数

每个数的约数个数为(a1+1)*(a2+1)*...*(ak+1),首先如果数i是素数,可以直接得到约数个数w[i]=2,又由于线性筛的时候,每个数是被最小素因子筛掉,所以如果i%prime[j]!=0,那么prime[j]将是i*prime[j]的最小素数,并且个数为1,所以w[i*prime[j]]=w[i]*(1+1),如果i%prime[j]==0,那么prime[j]既是i*prime[j]的最小素数,又是i的最小素数(因为prime[j]是i*prime[j]的最小素数嘛,所以不可能存在比prime[j]更小的素数),所以此时w[i*prime[j]]=w[i]/(n[i]+1)*(n[i*prime[j]]+1),其中n[i]表示i的最小素数的个数,那么显然n[i*prime[j]]=n[i]+1

 1 void getprime(int siz){
 2     memset(isprime,1,sizeof(isprime));
 3     isprime[1]=0;
 4     for(int i=2;i<=siz;i++){
 5         if(isprime[i]){prime[++tot]=i;w[i]=2;ww[i]=1;}
 6         for(int j=1;j<=tot&&i*prime[j]<=siz;j++){
 7             isprime[i*prime[j]]=0;
 8             if(i%prime[j]!=0){
 9                 w[i*prime[j]]=w[i]*2;
10                 ww[i*prime[j]]=1;
11             }
12             else{
13                 ww[i*prime[j]]=ww[i]+1;
14                 w[i*prime[j]]=w[i]/(ww[i]+1)*(ww[i*prime[j]]+1);
15                 break;
16             }
17         }
18     }
19 }

 

以上是关于[线性筛][筛素数/筛约数个数]的主要内容,如果未能解决你的问题,请参考以下文章

bzoj千题计划204:bzoj1968: [Ahoi2005]COMMON 约数研究(线性筛约数个数)

SIEVE 线性筛

模板 - 数论 - 线性筛

线性筛--如何线性求约数个数

筛素数算法——线性筛素数算法

线性筛约数个数和(证明)