定义
在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目,(varphi(1)=1)。
计算
两种计算方式
1.直接计算
(varphi(x)=x prodlimits_{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 imes Pi_{pin prime,p|x}(1-frac 1p))
以上的证明:(用归纳证明)
设(p,qin 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 imes (1-frac xp-frac xq+frac x{pq})=x imes (1-frac 1p) imes(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);
}
}
}