欧拉函数:
设 n 为正整数,则 1,2,……,n 中与 n 互素的整数的个数计作 ϕ(n) ,叫做欧拉函数。
相关性质:
设 p 是素数, ϕ(p)=p−1
设 p 是素数, ϕ(pa)=pa−pa−1
设 p, q 是不同的素数,n = q * p, ϕ(n)=ϕ(p)∗ϕ(q) ,即 ϕ(n)=(p−1)∗(q−1)
设 m, n 是两个正整数,且 (m, n) = 1,若 N = m * n, ϕ(N)=ϕ(m)∗ϕ(n)
设 m, n 是两个正整数,且 (m, n) = d,若 N = m * n, ϕ(N)=ϕ(m)∗ϕ(n)∗dϕ(d)
设 m, n 是两个正整数,且 m = k * n,若 N = m * n, ϕ(N)=ϕ(m)∗n
若正整数 a,b,满足 a∣b ,则有 ϕ(a)∣ϕ(b)
设 N = p1q1 * p2q2 * … * pnqn ,则 ϕ(N) = N * (1−1p1) * (1−1p2) * … * (1−1pn)
欧拉定理:
设 m 是大于 1 的整数,若整数 a 满足 (a, m) = 1,则有 aϕ(m)=1(modm) .
相关代码:
单独求欧拉函数:
int euler (int x) {
int ans = x;
for (int i = 2; i < (int)sqrt(x * 1.0) + 1; i++) {
if (x % i == 0) {
ans = ans / i * (i - 1);
while (x % i == 0) {
x /= i;
}
}
}
if (x > 1) {
ans -= ans / x;
}
return ans;
}
线性求素数和欧拉函数:
const int N = 100005;
bool is[N];
int pri[N];
int phi[N];
int tot;
void phi_pri_init () {
memset(is, true, sizeof(is));
memset(pri, 0, sizeof(pri));
memset(phi, 0, sizeof(phi));
tot = 0;
is[0] = is[1] = 0;
for (int i = 2; i < N; i++) {
if (is[i]) {
pri[++tot] = i;
phi[i] = i - 1;
}
for (int j = 1; j < tot && pri[j]*i < N; j++) {
is[pri[j]*i] = 0;
if (i % pri[j] == 0) {
phi[i*pri[j]] = phi[i] * pri[j];
break;
}
else {
phi[i*pri[j]] = phi[i] * (pri[j] - 1);
}
}
}
}