标签:style blog http color os ar strong for art
埃氏筛法:从2开始,找到第一个没有被筛的数,把它标记为素数,然后把它的2倍、3倍……筛掉。
复杂度O(nlogn)
。
改进的埃氏筛法:从2开始,找到第一个没有被筛的数x
,把它标记为素数,然后把它的x
倍、x+1
倍……筛掉。
复杂度O(nloglogn)
。
线性筛:保证每个数都被它的最小素因子筛掉。
复杂度O(n)
。
C++写起来大概是这样的:
int mindiv[10000005],tot,prime[10000050]; int main(){ for(int i=2;i<=10000000;i++){ if(!mindiv[i]){ mindiv[i]=i;prime[tot++]=i; } for(int j=0;prime[j]*i<=10000000;j++){ mindiv[prime[j]*i]=prime[j]; if(prime[j]==mindiv[i]) break; //! } } return 0; }
上述代码求得[1,1000w]的素数,本机Core i3运行用时0.14s,还是很快的。
其中,mindiv[x]保存了x的最小素因子,用它有很多用处(例如分解质因数什么的)。
筛积性函数
积性函数就是指:对于正整数n的一个算术函数 f(n),且当a,b互质时f(ab)=f(a)f(b)。
如:欧拉函数,莫比乌斯函数。
下面以筛欧拉函数为例:
φ(x)表示1~x中与x互质的数的个数。
这样我们就可以把所有数分成若干类:
在筛素数的时候分别处理这三种情况即可。
1 int mindiv[10000005],tot,prime[10000050],phi[10000050]; 2 int main(){ 3 for(int i=2;i<=10000000;i++){ 4 if(!mindiv[i]){ 5 mindiv[i]=i;prime[tot++]=i;phi[i]=i-1;//1 6 } 7 for(int j=0;prime[j]*i<=10000000;j++){ 8 mindiv[prime[j]*i]=prime[j]; 9 if(prime[j]==mindiv[i]){ 10 phi[prime[j]*i]=phi[i]*prime[j] ;break;//2 11 } 12 phi[prime[j]*i]=phi[i]*(prime[j]-1);//3 13 } 14 } 15 return 0; 16 }
这样就求出了2~1000w的欧拉函数。
方便快捷。
标签:style blog http color os ar strong for art
原文地址:http://www.cnblogs.com/zrts/p/3960985.html