素数线性筛、欧拉函数线性筛
这俩算法,可以在线性时间内,筛素数的同时,求出所有数的欧拉函数。
参考博客:
素数线性筛原理:https://www.cnblogs.com/xiaodeshan/p/7811344.html
素数线性筛代码实现:https://blog.csdn.net/litoupu/article/details/11020885
素数线性筛 扩展到 欧拉函数线性筛:https://blog.csdn.net/pengwill97/article/details/77509425
一、线性素数筛
线性素数筛原理:
原始的埃氏筛选法,效率已经不低了,但是会有很多的重复计算,即一个数会被多次踢出,浪费了计算时间。
现在,线性素数筛,可以保证,每个合数只被踢出一次。
即,保证每个合数,都被其最小的质因数筛去。
实现方法是:
如果当前数 i,被发现可以整除某个已经确定了的质数,那么当前数 i 就不必再往下看了,直接break,进入下一个数。
为什么可以这样做呢?
因为这样一来,当前数 i 就可以被确定是一个合数;
任意一个合数和一个质数的乘积,都可以用一个更大的合数和一个更小的质数的乘积表示;
当前数 i 本来可以构成的所有合数( i*prime[0] , i*prime[1] , i*prime[2] ……),都肯定之前已经被踢出过了,不必再重复计算了
(每个合数必有一个最小素因子,每个合数肯定能够由素数的相乘得到。)
(每个合数仅被它的最小素因子筛去正好一次。所以为线性时间。)
线性素数筛模板:
bool is_prime[MAX]; //记录每个数是否为素数 void makePrime2() { vector<int> prime; //存储到现在为止,所有已经确定的素数 memset(is_prime,0,sizeof(is_prime)); for(int i=2;i<=MAX;i++) //从i=2开始(乘两倍起步) { if(is_prime[i]==0) prime.push_back(i); for(int j=0; j<prime.size() && i*prime[j]<=MAX; j++) //最大筛到MAX为止 { is_prime[i*prime[j]]=1; if(i%prime[j]==0) break; } } }
解释:
1:各个数组的意义:
is_prime [MAX]:记录每个数是否为素数
vector<int> prime: 存储到现在为止,所有已经确定的素数
2:最外层for循环的意义:
i=2 就表示,所有现在已经确定的素数(vector prime 里面所有的数),每一个都乘2,所得的数,全部筛掉
i=3 就表示,所有现在已经确定的素数,每一个都乘3,所得的数,全部筛掉
…………
3:请注意第十五行的 break ,这里是精髓。
具体为什么写,见上方“线性素数筛原理”。
二、欧拉函数线性筛
欧拉函数线性筛原理:
欧拉函数线性筛,代码基本和素数线性筛一样,只不过是在筛出素数的时候,顺便在同时,筛出各个数的欧拉函数值
利用素数合数信息,推出欧拉函数值的方法:(欧拉函数的几条性质)
1:当n为质数的时候,φ(n)=n−1。
2:欧拉函数是积性函数,但不是完全积性。当n,m互质的时候,φ(n∗m)=φ(n)∗φ(m)。
(其实欧拉函数还有以下一些性质,不过他们与此次博文主题不相关)
3:当n为奇数的时候,φ(2∗n)=φ(n)。
4:除了φ(2)时,其他欧拉函数均为偶数。
5:小于n,且与n互质的所有数字的和是φ(n)∗n/2。
线性欧拉筛的代码模板:
(在素数线性筛的基础上改造,一边筛选素数,一边顺便利用性质,算出每个数的对应的欧拉函数值)
vector<int> prime; //记录看到现在为止的每个素数 bool is_prime[maxn+5]; //记录每个数是否是素数 int phi[maxn+5]; //存储每个数对应的欧拉函数值 void init() { memset(is_prime,0,sizeof(is_prime)); phi[1]=1; //赋初始值:phi[1]=1; for(int i=2;i<=maxn;i++) { if(is_prime[i]==0) { prime.push_back(i); phi[i]=i-1; //参考性质1 } for(int j=0;j<prime.size() && i*prime[j]<=maxn;j++) { is_prime[i*prime[j]]=1; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; //这里好好理解一下 break; } else { phi[i*prime[j]]=phi[i]*(prime[j]-1); //参考性质2 } } } }
欧拉的应用实例:
http://acm.hdu.edu.cn/showproblem.php?pid=6434
浙公网安备 33010602011771号