欧拉函数
定义
欧拉函数(Euler’s totient function),即 ,表示的是小于等于 和 互质的数的个数。
当 是质数的时候,显然有 。
计算
若在算数基本定理中,
证明:
设 是 的质因子, 中 的倍数有 共 个。同理,若 也是 的质因子,则 中 的倍数有 个。如果我们把这 个书去掉,那么 的倍数被排除了两侧,需要加回来一次(容斥原理)。因此 , 中不与 含有任何共同质因子 或 的个数为:
类似的,可以对 的所有质因子进行上述操作即可得到
证毕。
故,我们只需分解质因数,即可顺利求出欧拉函数。
int Phi(int n) {
int Ans = n;
for(int i = 2; i <= sqrt(n); i++) {
if(n % i == 0) {
Ans = Ans / i * (i - 1);
while(n % i == 0) n /= i;
}
}
if(n > 1) Ans = Ans / n * (n - 1);
return Ans;
}
性质
基本性质
- 中与 互质的数的和为
- 若 ,则
证明:
因为 ,所以与 互质的数成对出现,每对的和为 ,共有 对,所以和为 ,性质 显然成立
根据欧拉函数的计算式,对 分解质因数,可以得到性质 。即为 欧拉函数是积性函数
证毕。
积性函数
如果 ,有 ,那么称函数 为积性函数。
其他性质
- 若 为积性函数,且在算数基本定理中 ,则
- 设 为质数,若 且 ,则
- 设 为质数,若 且 ,则
线性筛
由于欧拉函数是积性函数,所以可以线性筛,代码见下
for(int i = 2; i <= n; i++) {
if(!vis[i]) { //i是质数
prime[primen++] = i;
phi[i] = i - 1; //质数的欧拉函数是比它少一
}
for(int j = 0; j < primen; j++) {
if(i*prime[j] > n) break;
vis[i*prime[j]] = 1;
if(i % prime[j] != 0)
//积性函数
phi[i*prime[j]] = phi[i] * phi[prime[j]];
else{
//若x是质数p的倍数,则phi[x]=phi[x/p]*p
phi[i*prime[j]] = phi[i] * prime[j];
break; //保证只筛一次
}
}
}