前置知识
线性筛质数
积性函数定义:若一个定义域在正整数上的函数
f
(
x
)
f(x)
f(x) 满足
∀
x
,
y
∈
N
+
且
gcd
(
x
,
y
)
=
1
,
f
(
x
y
)
=
f
(
x
)
f
(
y
)
\forall x,y\in N_+\text{且} \gcd(x,y)=1,f(xy)=f(x)f(y)
∀x,y∈N+且gcd(x,y)=1,f(xy)=f(x)f(y)
凡是积性函数,都可以用线性筛。
剖析线性筛质数
回顾整个算法,我们发现每个正整数都只会被它的最小质因子筛掉,故整个算法的时间复杂度为
O
(
n
)
O(n)
O(n)。
这里给出参考代码:
void ola(int x){
pr[1]=1;
for(int i=1;i<=x;i++){
if(!pr[i])
prv[++cnt]=i;
for(int j=1;j<=cnt&&i*prv[j]<=x;j++){
pr[i*prv[j]]=1;
if(i%prv[j]==0)
break;
}
}
}
于是我们就可以以此为基础筛一些积性函数了。
欧拉函数
定义
欧拉函数
φ
(
n
)
\varphi(n)
φ(n) 表示小于等于
n
n
n,且与
n
n
n 互质的正整数的个数。特别的,
φ
(
1
)
=
1
\varphi(1)=1
φ(1)=1
求单个欧拉函数
设
n
=
∏
i
=
1
q
p
i
x
i
n=\prod_{i=1}^qp_i^{x_i}
n=∏i=1qpixi(质因数分解,如无特殊说明,下文此形式均为质因数分解),集合
A
i
A_i
Ai 表示不大于
n
n
n 且是
p
i
p_i
pi 的倍数的自然数的集合。
所有
∣
A
i
∣
=
n
p
i
|A_i|=\frac{n}{p_i}
∣Ai∣=pin
因为
gcd
(
p
i
,
p
j
)
=
1
(
i
≠
j
)
\gcd(p_i,p_j)=1(i\ne j)
gcd(pi,pj)=1(i=j)
所以
∣
A
i
∩
A
j
∣
=
n
p
i
p
j
|A_i\cap A_j|=\frac{n}{p_ip_j}
∣Ai∩Aj∣=pipjn
再结合容斥:
参考代码:
int getphi(int x){
int res=x;
for(int i=2;i*i<=x;i++){
if(x%i==0)
res=res*(i-1)/i;
while(x%i==0)
x/=i;
}
if(x>1)
res=res*(x-1)/x;
return res;
}
欧拉函数是积性函数
证明:
φ
(
n
)
φ
(
m
)
=
n
∏
i
=
1
x
(
1
−
1
p
i
)
m
∏
i
=
x
+
1
x
+
y
(
1
−
1
p
i
)
=
φ
(
n
m
)
\varphi(n)\varphi(m)=n\prod_{i=1}^x(1-\frac{1}{p_i})m\prod_{i=x+1}^{x+y}(1-\frac{1}{p_i})=\varphi(nm)
φ(n)φ(m)=ni=1∏x(1−pi1)mi=x+1∏x+y(1−pi1)=φ(nm)
由于
gcd
(
n
,
m
)
=
1
\gcd(n,m)=1
gcd(n,m)=1,所以
n
,
m
n,m
n,m的每个质因子必不相同,所以得证。
性质
- 若 n n n 是质数, φ ( n ) = n − 1 \varphi(n)=n-1 φ(n)=n−1
- 若 p p p 为质数,且 n = p k n=p^k n=pk,则 φ ( n ) = ( p − 1 ) p k − 1 \varphi(n)=(p-1)p^{k-1} φ(n)=(p−1)pk−1
- 若 q q q 为质数,且 ∃ k ∈ N + \exists k\in N_+ ∃k∈N+ 使得 n = q k n=qk n=qk,则 φ ( n q ) = q φ ( n ) \varphi(nq)=q\varphi(n) φ(nq)=qφ(n)
- 若 q q q 为质数,且 ∀ k ∈ N + \forall k\in N_+ ∀k∈N+, n ≠ q k n\ne qk n=qk,则 φ ( n q ) = ( q − 1 ) φ ( n ) \varphi(nq)=(q-1)\varphi(n) φ(nq)=(q−1)φ(n)
- n = ∑ d ∣ n φ ( d ) n=\sum_{d|n}\varphi(d) n=∑d∣nφ(d)
- φ ( a b ) = φ ( a ) φ ( b ) d φ ( d ) \varphi(ab)=\varphi(a)\varphi(b)\frac{d}{\varphi(d)} φ(ab)=φ(a)φ(b)φ(d)d,其中 d = gcd ( a , b ) d=\gcd(a,b) d=gcd(a,b)
证明
- 不证
- φ ( n ) = n ( 1 − 1 p ) = p k p − 1 p = ( p − 1 ) p k − 1 \varphi(n)=n(1-\frac{1}{p})=p^k\frac{p-1}{p}=(p-1)p^{k-1} φ(n)=n(1−p1)=pkpp−1=(p−1)pk−1
- φ ( n q ) = n q ∏ i = 1 x ( 1 − 1 p i ) = q n ∏ i = 1 x ( 1 − 1 p i ) = q φ ( n ) \varphi(nq)=nq\prod_{i=1}^x(1-\frac{1}{p_i})=qn\prod_{i=1}^x(1-\frac{1}{p_i})=q\varphi(n) φ(nq)=nq∏i=1x(1−pi1)=qn∏i=1x(1−pi1)=qφ(n)
- n = ∏ i = 1 y p i x i , φ ( n q ) = n q ( 1 − 1 q ) ∏ i = 1 y ( 1 − 1 p i ) = q q − 1 q [ n ∏ i = 1 y ( 1 − 1 p i ) ] = ( q − 1 ) φ ( n ) n=\prod_{i=1}^yp_i^{x_i},\varphi(nq)=nq(1-\frac{1}{q})\prod_{i=1}^y(1-\frac{1}{p_i})=q\frac{q-1}{q}[n\prod_{i=1}^y(1-\frac{1}{p_i})]=(q-1)\varphi(n) n=∏i=1ypixi,φ(nq)=nq(1−q1)∏i=1y(1−pi1)=qqq−1[n∏i=1y(1−pi1)]=(q−1)φ(n)
- 如图
理性理解: n = ∑ d ∣ n ∑ i = 1 n [ gcd ( i , n ) = d ] = ∑ d ∣ n ∑ i = 1 n d [ gcd ( i , n d ) = 1 ] = ∑ d ∣ n φ ( n d ) = ∑ d ∣ n φ ( d ) \large{n=\sum_{d|n}\sum_{i=1}^n[\gcd(i,n)=d]=\sum_{d|n}\sum_{i=1}^\frac{n}{d}[\gcd(i,\frac{n}{d})=1]=\sum_{d|n}\varphi(\frac{n}d{})=\sum_{d|n}\varphi(d)} n=∑d∣n∑i=1n[gcd(i,n)=d]=∑d∣n∑i=1dn[gcd(i,dn)=1]=∑d∣nφ(dn)=∑d∣nφ(d)
d = ∏ i = 1 q 1 p 1 i x 1 i , a = ∏ i = 1 q 2 p 2 i x 2 i , b = ∏ i = 1 q 3 p 3 i x 3 i φ ( a b ) = a b ∏ i = 1 q 2 ( 1 − 1 p 2 i ) ∏ i = 1 q 3 ( 1 − 1 p 3 i ) ∏ i = 1 q 1 ( 1 − 1 p 1 i ) = φ ( a ) φ ( b ) 1 d φ ( d ) = φ ( a ) φ ( b ) d φ ( d ) \large{d=\prod_{i=1}^{q_1}{p_{1i}}^{x_{1i}},a=\prod_{i=1}^{q_2}{p_{2i}}^{x_{2i}},b=\prod_{i=1}^{q_3}{p_{3i}}^{x_{3i}}}\\\varphi(ab)=\frac{ab\prod_{i=1}^{q_2}(1-\frac{1}{p_{2i}})\prod_{i=1}^{q_3}(1-\frac{1}{p_{3i}})}{\prod_{i=1}^{q_1}(1-\frac{1}{p_{1i}})}=\frac{\varphi(a)\varphi(b)}{\frac{1}{d}\varphi(d)}=\varphi(a)\varphi(b)\frac{d}{\varphi(d)} d=i=1∏q1p1ix1i,a=i=1∏q2p2ix2i,b=i=1∏q3p3ix3iφ(ab)=∏i=1q1(1−p1i1)ab∏i=1q2(1−p2i1)∏i=1q3(1−p3i1)=d1φ(d)φ(a)φ(b)=φ(a)φ(b)φ(d)d
线性筛欧拉函数
回顾性质
1
,
3
,
4
1,3,4
1,3,4,也就是我们筛欧拉函数的基础了,即我们在筛质数的时候顺便把欧拉函数也给筛出来。
参考代码:
void ola(int x){
pr[1]=phi[1]=1;
for(int i=1;i<=x;i++){
if(!pr[i])
prv[++cnt]=i,phi[i]=i-1;
for(int j=1;j<=cnt&&i*prv[j]<=x;j++){
int u=i*prv[j];
pr[u]=1;
if(i%prv[j]==0){
phi[u]=phi[i]*prv[j];
break;
}
else{
phi[u]=phi[i]*(prv[j]-1);
}
}
}
}
d ( x ) d(x) d(x)
设 d ( x ) d(x) d(x) 表示 x x x 的约数的个数。
-
d ( x ) d(x) d(x) 是积性函数。
证明:
A = ∏ i = 1 n p i x i , B = ∏ i = 1 m q i y i , n = A B , g c d ( A , B ) = 1 d ( A ) = ∏ i = 1 n ∑ j = 0 x i p i j , d ( B ) = ∏ i = 1 m ∑ j = 0 y i q i j ∵ gcd ( A , B ) = 1 , ∴ n = ∏ i = 1 n p i x i ∏ i = 1 m q i y i ∴ d ( n ) = ∏ i = 1 n ∑ j = 0 x i p i j ∏ i = 1 m ∑ j = 0 y i q i j ∴ d ( n ) = d ( A ) d ( B ) \large{A=\prod_{i=1}^np_i^{x_i},B=\prod_{i=1}^mq_i^{y_i},n=AB,gcd(A,B)=1}\\ d(A)=\prod_{i=1}^n\sum_{j=0}^{x_i}p_i^{j},d(B)=\prod_{i=1}^m\sum_{j=0}^{y_i}q_i^{j}\\ \because \gcd(A,B)=1,\therefore n=\prod_{i=1}^np_i^{x_i}\prod_{i=1}^mq_i^{y_i}\\ \therefore d(n)=\prod_{i=1}^n\sum_{j=0}^{x_i}p_i^{j}\prod_{i=1}^m\sum_{j=0}^{y_i}q_i^{j}\\ \therefore d(n)=d(A)d(B) A=i=1∏npixi,B=i=1∏mqiyi,n=AB,gcd(A,B)=1d(A)=i=1∏nj=0∑xipij,d(B)=i=1∏mj=0∑yiqij∵gcd(A,B)=1,∴n=i=1∏npixii=1∏mqiyi∴d(n)=i=1∏nj=0∑xipiji=1∏mj=0∑yiqij∴d(n)=d(A)d(B) -
线性筛 d ( x ) d(x) d(x):
- 参考代码:
void ola(int x){
pr[1]=d[1]=1;
for(int i=1;i<=x;i++){
if(!pr[i])
prv[++cnt]=i,d[i]=2,mx[i]=i,mi[i]=1;
for(int j=1;j<=cnt&&i*prv[j]<=x;j++){
int u=i*prv[j];
pr[u]=1;
if(i%prv[j]==0){
mi[u]=mi[i]+1;
mx[u]=mx[i]*prv[j];
d[u]=(mx[u]==u?mi[u]+1:d[mx[u]]*d[u/mx[u]]);
break;
}
else{
mi[u]=1;
mx[u]=prv[j];
d[u]=d[mx[u]]*d[u/mx[u]];
}
}
}
}