欧拉函数
欧拉函数
欧拉函数的定义
欧拉函数(Euler's totient function),求小于或者等于\(n\)的数中与\(n\)互质的数的个数,记为:\(\varphi(n)\)。
欧拉函数的通式\(\varphi \left( n\right) =n\left( 1-\dfrac {1} {p_{1}}\right) \left( 1-\dfrac {1} {p_{2}}\right) \ldots \left( 1-\dfrac {1} {p_{n}}\right)\),其中\(p_1,p_2,\dots,P_n\)都是\(n\)的质因数。
比如:\(\varphi(1)=1\)。
当\(n\)时质数的时候,显然有\(\varphi(n)=n-1\)。
欧拉函数的一些性质
-
欧拉定理:若\(a,n\)为正整数,\(gcd(a,n)=1\),则\(a^{\varphi(n)} \Xi \:1(mod\:n)\)。
-
若\(n\)是质数,则\(\varphi(n)=n-1\)。
若\(n\)是合数,则\(\varphi(n)\)自己算去吧!!!
-
欧拉函数是积性函数:
若\(n,m\)互质,则\(\varphi(n\times m)=\varphi(n)\times \varphi(m)\)。
当\(n\)为奇数时,有\(\varphi(2\times n)=\varphi(n)\)。
若\(n=p^k\)且\(P\)是质数,则\(\varphi(n)=p^k-p^{k-1}\)。
-
除了\(n=2\),\(\varphi(n)\)都是偶数。
如何求欧拉函数值
在这里,我们先求一个数的欧拉函数值,这样我们可以直接根据定义质因数分解的同时求解。时间复杂度为\(O(N)\)。
int oula(int n){
int res = n;
for(int i = 2; i * i <= n; i++){//n的素因子定在sqrt(n)内
if(n % i == 0){
res = res - res / i;//res = res - res / i是由n*(1-1/i)化来的,在这里不允许有小数,都是整数运算
while(n % i == 0) n /= i;
}
}
if(n > 1) res = res - res / n;
return res;
}
那么对于多个数的欧拉函数值,我们是是否可以进行线性筛选呢?答案是可以的。
\(\varphi \left( n\right) =n\left( 1-\dfrac {1} {p_{1}}\right) \left( 1-\dfrac {1} {p_{2}}\right) \ldots \left( 1-\dfrac {1} {p_{n}}\right)\),其中\(p_1,p_2,\dots,P_n\)都是\(n\)的质因数。
例如:\(\varphi(12)=12\times(1-\frac{1}{2})\times(1-\frac{1}{3})=4\).
利用这个我们可以类似求素数的的筛法。先筛出N以内的所有素数,再以素数筛每个数的φ值。
比如求8以内所有数的φ值:设一个数组\(phi[9]\),初始值为\(phi[1]=1,phi[2]=2,\dots,phi[8]=8\),然后从\(2\)开始循环,把\(2\)的倍数的\(\varphi\)值都乘以\((1-\frac{1}{2})\);再是把\(3\)的倍数的\(\varphi\)值都乘以\((1-\frac{1}{3})\dots\)。(这里有点运用了素数的埃氏筛选的思想)。对于每一个素数都进行如此操作,就相当于任何一个\(n\)都进行了\(\varphi \left( n\right) =n\left( 1-\dfrac {1} {p_{1}}\right) \left( 1-\dfrac {1} {p_{2}}\right) \ldots \left( 1-\dfrac {1} {p_{n}}\right)\)的运算。
const int MAXN = 2e5 + 10;
int oula[MAXN];
void Inou(){
for(int i = 1; i <= MAXN; i++){
oula[i] = i;
}
for(int i = 2; i <= MAXN; i++){
if(oula[i] == i){//素数在之前是不会被任何数筛的
for(int j = i; j <= MAXN; j += i){
oula[j] = oula[j] - oula[j] / i;
}
}
}
}
如果以上内容有错误的地方,请在下面评论指出,谢谢了!!!

浙公网安备 33010602011771号