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

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

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 }

 

posted @ 2019-05-23 12:52  MekakuCityActor  阅读(254)  评论(0编辑  收藏  举报