互质与欧拉函数
1. 算法分析
基本概念
欧拉函数:1~N中与N互质的数的个数
在算术基本定理中:N = (p1a1) * (p2a2) * … *(pmam)
一个数的欧拉函数: φ(N)=N * (1-1/p1) * (1-1/p2) * … * (1-1/pm)
且φ(1) = φ(2) = 1
重要结论
1~N中,(x, y) = 1的对数为: 前1~N的欧拉函数的前缀和 * 2 - 1
常用思路
很多求gcd(x, y)=p的问题,最后都需要转化为(x/p, y/p)=1,然后变为求互质的数目,转化为欧拉函数求解
2. 板子
- 求N的欧拉函数 O(sqrt(N))
int get_euler(int a) {
long long res = a; // 存储答案
for (int i = 2; i <= a / i ;++i) {
// 求出小于等于sqrt(a)的质数
if (a % i == 0) {
res = res * (i - 1) / i; // 欧拉函数公式求答案
while (a % i == 0) a /= i;
}
}
if (a > 1) res = res * (a - 1) / a;
return res;
}
- 求1~N的欧拉函数和 O(N)
phi[1] = 1;
long long res = 0;
for (int i = 2; i <= n; ++i ) {
// 求质数
if (!st[i]) {
// 没记录就标记这个质数
prime[cnt++] = i;
phi[i] = i - 1; // 质数的欧拉函数为本身减一
}
for (int j = 0; prime[j] <= n / i; ++j) {
// 枚举所有的质数
st[prime[j] * i] = 1;
if (i % prime[j] == 0 ) {
// 如果i能够整除pj
phi[i * prime[j]] = prime[j] * phi[i]; // phi(i * pj) = pj * phi[i]
break;
}
phi[i * prime