线性筛中每个数只会被最小的素因子筛一次
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 }