欧拉函数
定义
欧拉函数,写作 \(\varphi(n)\),表示小于等于 \(n\) 的数中和 \(n\) 互质的数的个数。
性质
-
当 \(n\) 是质数的时候,有 \(\varphi(n) = n - <1\)
-
欧拉函数是积性函数。
积性:如果有 \(gcd(a,b) = 1\),那么 \(\varphi(a×b) = \varphi(a) × \varphi(b)\)。
-
\(n = \sum_{d\mid n}{\varphi(d)}\)。
可以这样考虑:如果 \(gcd(k,n) = d\),那么 \(n = \sum_{i = 1}^n{f(i)}\)。
证明:\(k <= n\),对于 \(1-n\) 中每个 \(k\) 和 \(n\) 的 \(gcd\) 是固定的,这些 \(gcd\) 的范围是 \(1-n\) 所以对于每一个 \(k\) 都会产生一个贡献,最后一共会产生 \(n\) 的贡献。
由以上的证明,可以发现,\(f(x) = \varphi(\frac{n}{x})\),从而 \(n=\sum_{d \mid n}\varphi{\frac{n}{d}}\)。注意到 \(d\) 和 \(\frac{n}{d}\) 具有对称性,所以可以继续化简为 \(n=\sum_{d \mid n}\varphi(d)\)。
证明:考虑每一个 \(x\) 的贡献,而不是 \(k\) 的贡献,那么只有 \(x\) 是 \(n\) 的因数时才会产生贡献。
对于 \(k <= n, gcd(k,n)=x\),那么对于 \(k <= \frac{n}{x}, gcd(k,\frac{n}{x}) = 1\),那当前这个 \(x\) 能产生的贡献就是 \(\varphi(\frac{n}{x})\),那么 \(n=\sum_{d \mid n}\varphi{\frac{n}{d}}\)。
-
若 \(n=p^k\),其中 \(p\) 是质数,那么 \(\varphi(n) = p^k-p^{k-1}\)。
证明:考虑 \(\varphi(n)\) 的定义,小于等于 \(n\) 中与 \(n\) 互质的数的个数,那我们要求 \(\varphi(n)\) ,只要求与小于等于 \(n\) 的数中与 \(n\) 不互质的数的个数即可。
因为 \(n = p^k\),所以小于等于 \(n\) 的数中,与其不互质的数,也就是含有 \(p\) 这个因数的数的个数为 \(\frac{n}{p}\),即 \(\frac{p^k}{p}\),即 \(p^{k-1}\)。所以小于等于 \(n\) 的数中,与其互质的数的个数为 \(p^k - p^{n-1}\)。
-
由唯一分解定理,设 \(n=\prod_{i=1}^{s}p_i^{k_i}\),其中 \(p_i\) 是质数,有 \(\varphi(n)=n\times\prod_{i=1}^{s}\frac{p_i-1}{p_i}\)。
证明:
- 引理:设 \(p\) 为任意质数,那么 \(\varphi(p^k) = p^{k-1}\times(p-1)\)。
证明:因为上边一条性质,转化一下:\[\varphi(p^k) = p^k-p^{k-1}=p^{k-1}\times(p-1) \]由唯一分解定理和函数积性。
\[\varphi(n)=\prod_{i=1}^s\varphi(p_i^{k_i})\\ =\prod_{i=1}^s(p_i-1)\times(p_i^{k_i-1})\\ =\prod_{i=1}^sp_i^{k_i}\times(1-\frac{1}{p_i})\\ =n\prod_{i=1}s(1-\frac{1}{p_i}) \]
求欧拉函数值
如果只要求一个数的欧拉函数值,只要边跑质因数分解边求就可qwq
Euler_phi
void Euler_phi(int n) {
int ans = n;
for(int i = 2; i <= sqrt(n); ++ i) {
if(!(n % i)) {
ans = ans / i * (i - 1);
while(!(n % i)) n /= i;
}
}
if(n > 1) ans = ans / i * (i - 1);
return ans;
}
在线性筛中,每一个合数都是被最小质因子筛掉的。设 \(p_1\) 是 \(n\) 的最小质因子,\(n'=\frac{n}{p_1}\),那么线性筛的过程中,\(n\) 会通过 \(n'\times p_1\) 筛掉。
分为两个部分,下面为分类讨论。
若 \(n' \bmod p_1 = 0\),那么 \(n'\) 包含了 \(n\) 的所有质因子。
若 \(n' \bmod p_1 \neq 0\),这时 \(n'\) 与 \(p_1\) 是互质的,根据欧拉函数的性质,得
筛法中 \(i\) 表示 \(n'\),\(prime[j]\) 表示 \(p_1\)。
Pre
void Pre() {
memset(numlist, 1, sizeof numlist);
int cnt = 0;
numlist[1] = 0;
phi[1] = 1;
for(int i = 2; i <= 50000000; ++ i) {
if(numlist[i]) {
prime[++ cnt] = i;
phi[i] = i - 1;
}
for(int j = 1; j <= cnt && i * prime[j] <= 50000000; ++ i) {
numlist[i * prime[j]] = 0;
if(i % prime[j] == 0) phi[i * prime[j]] = phi[i] * phi[prime[j]];
else {
prime[i * prime[j]] = prime[j] * phi[i];
break;
}
}
}
}