1.欧拉函数证明
欧拉函数:对于一个正整数n,在1~n中与n互质的数的个数
对于正整数 n n n, p 1 , p 2 , ⋯ , p k p_1,p_2, \cdots,p_k p1,p2,⋯,pk是n的k个质因子
欧拉函数的公式如下:
p
h
i
(
n
)
phi(n)
phi(n) =
n
n
n
×
\times
× (1 -
1
p
1
\frac{1}{p_1}
p11)
×
\times
× (1 -
1
p
2
\frac{1}{p_2}
p21)
×
\times
×
⋯
\cdots
⋯
×
\times
× (1 -
1
p
k
\frac{1}{p_k}
pk1) ①
那么对于另一种方式:由于唯一分解定理,我们可以考虑将这 k k k个质因子的所有倍数筛去,那么得到的结果就是欧拉函数
p h i ( n ) phi(n) phi(n)= n n n − - − n p 1 \frac{n}{p_1} p1n − - − n p 2 \frac{n}{p_2} p2n − - − n p 3 \frac{n}{p_3} p3n − - − ⋯ \cdots ⋯ − - − n p k \frac{n}{p_k} pkn + + + n p 1 ∗ p 2 \frac{n}{p_1*p_2} p1∗p2n + + + ⋯ \cdots ⋯ + + + n p n − 1 ∗ p n \frac{n}{p_{n-1}*p_{n}} pn−1∗pnn − - − n 奇 数 个 质 因 子 相 乘 \frac{n}{奇数个质因子相乘} 奇数个质因子相乘n + + + n 偶 数 个 质 因 子 相 乘 \frac{n}{偶数个质因子相乘} 偶数个质因子相乘n ⋯ \cdots ⋯②
将①式展开会发现与②式相同,所以得证
2.欧拉线性筛
对于多组询问如果每次都调用欧拉函数则会超时,所以预处理出一部分的欧拉函数就显得很有必要了。
将
N
N
N分解质因数
N
=
p
1
a
1
×
p
2
a
2
×
p
3
a
3
×
.
.
.
×
p
k
−
1
a
k
−
1
×
p
k
a
k
N={p_1}^{a_1}\times {p_2}^{a_2}\times {p_3}^{a_3}\times...\times{p_{k-1}}^{a_{k-1}}\times p_k^{a_k}
N=p1a1×p2a2×p3a3×...×pk−1ak−1×pkak
ϕ
(
N
)
=
N
×
\phi(N)=N\times
ϕ(N)=N× (1 -
1
p
1
\frac{1}{p_1}
p11)
×
\times
× (1 -
1
p
2
\frac{1}{p_2}
p21)
×
\times
×
⋯
\cdots
⋯
×
\times
× (1 -
1
p
k
\frac{1}{p_k}
pk1)
① 对于质数,其欧拉函数为值减
1
1
1,如
p
h
i
(
5
)
=
5
−
1
=
4
phi(5) = 5 - 1 = 4
phi(5)=5−1=4
② 当
i
i
i %
p
r
i
[
j
]
=
=
0
pri[j] == 0
pri[j]==0, 我们可以发现i中存在
p
r
i
[
j
]
pri[j]
pri[j],因此令
t
t
t
=
i
= i
=i
∗
*
∗
p
r
i
[
j
]
pri[j]
pri[j],即
p
r
i
[
j
]
pri[j]
pri[j]的贡献在
N
N
N这个地方得到了体现,则
p
h
i
(
t
)
=
p
h
i
(
i
)
phi(t) = phi(i)
phi(t)=phi(i)
∗
*
∗
p
r
i
[
j
]
pri[j]
pri[j]
③ 当
i
i
i %
p
r
i
[
j
]
!
=
pri[j] !=
pri[j]!=
0
0
0,我们发现i中不存在
p
r
i
[
j
]
pri[j]
pri[j],仍然令
t
t
t =
i
i
i
∗
*
∗
p
r
i
[
j
]
pri[j]
pri[j],即
p
r
i
[
j
]
pri[j]
pri[j]的贡献不仅体现在了
N
N
N这个地方,
t
t
t相比较于
i
i
i多了个
p
r
i
[
j
]
pri[j]
pri[j],即多了个
(
1
−
1
p
r
i
[
j
]
)
(1-\frac{1}{pri[j]})
(1−pri[j]1),则
p
h
i
(
t
)
phi(t)
phi(t) =
p
h
i
(
i
)
phi(i)
phi(i) *
p
r
i
[
j
]
pri[j]
pri[j] * (
1
1
1
−
-
−
1
p
r
i
[
j
]
\frac{1}{pri[j]}
pri[j]1)
即
p
h
i
(
t
)
phi(t)
phi(t)
=
=
=
p
h
i
(
i
)
phi(i)
phi(i)
∗
*
∗ (
p
r
i
[
j
]
−
1
pri[j] - 1
pri[j]−1)
int phi[N];
int pri[N], cnt; bool st[N];
void Euler(int n){
phi[1] = 1;
for(int i = 2; i <= n; i++){
if(!st[i]) {
pri[cnt++] = i;
phi[i] = i - 1;
}
for(int j = 0; j < cnt && i <= n / pri[j]; j++){
st[i * pri[j]] = true;
if(i % pri[j] == 0) {phi[i * pri[j]] = phi[i] * pri[j]; break;}
else phi[i * pri[j]] = phi[i] * (pri[j] - 1);
}
}
}