[数论]欧拉函数
定义
在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目,\(\varphi(1)=1\)。
计算
两种计算方式
\ 1.直接计算
\ \(\varphi(x)=x \prod\limits_{i=1}^n(1-\frac{1}{p_i})\),其中\(p_1,p_2,\dots,p_n\)为x的所有质因数,\(x\)是不为\(0\)的整数
引用@Chhokmah的证明
以下的除法指整除。
\(\varphi(x)\)是欧拉函数,表示的是\([1,x]\)中和\(x\)互质的数的个数。
\(\varphi(x)=x\times \Pi_{p\in prime,p|x}(1-\frac 1p)\)
以上的证明:(用归纳证明)
设\(p,q\in prime,p|x,q|x\),那么在\([1,x]\)中是\(p\)和\(q\)的倍数的个数分别为\(\frac xp\)和\(\frac xq\)。
那么存在于\([1,x]\)中是\(p\)或者\(q\)的倍数的个数为\(\frac xp+\frac xq-\frac x{pq}\)。(这一步用到了容斥原理)
那么\(\varphi(x)\)也就是和\(p,q\)同时不互质的数的个数为\(x-\frac xp-\frac xq+\frac x{pq}\)。
整一下上式得到\(x\times (1-\frac xp-\frac xq+\frac x{pq})=x\times (1-\frac 1p)\times(1-\frac 1q)\)。
归纳一下就可以得到\(\varphi\)的推导式了。
对于上式推导式,可以用暴力求,时间复杂度为\(O(\sqrt n)\)。
\ 2.递推计算
for(int i = 1; i <= maxn; ++i)
phi[i] = i;
for(int i = 2; i <= maxn; i += 2)
phi[i] >>= 1;
for(int i = 3; i <= maxn; i += 2)
if(phi[i] == i)
for(int j = i; j <= maxn; j += i)
phi[j] = phi[j] / i * (i - 1);
\ UPD:欧拉筛的做法
int phi[20000005];
int primes[20000005], pcnt;
bool isnp[20000005];
void getPhi(int num){
phi[1] = 1;
for (int i = 2; i <= num; ++i){
if (!isnp[i]) primes[++pcnt] = i, phi[i] = i - 1;
for (int j = 1; j <= pcnt && i * primes[j] <= num; ++j){
isnp[i * primes[j]] = 1;
if (!(i % primes[j])){phi[i * primes[j]] = phi[i] * primes[j]; break;}
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
}