欧拉函数及其拓展(积性函数)

前言

作者在OI生活早期的时候,经常遇到一些数学题不会,点开题解发现许多跟数论上的函数有关,题解的语言又晦涩难懂,从此对数学心有余悸,相信许多OIer也同样是如此。这几篇博客,作者将对OI数论中常出现的几个函数进行解读,希望读者能解开对数学的心结。

积性函数

概念

积性函数是对数论中一系列有特殊性质函数的统称,性质如下:

若gcd(a,b)=1, f(ab)=f(a)f(b),那么f则是积性函数。

特别地,假如对于任意的a、b,即gcd(a,b)≠1 也有f(ab)=f(a)f(b) ,那么称f是完全积性函数。

小扩展

一个有趣的事实:

对于函数g(n)=∑ d|n f(d),如果g是积性函数,那么f也是积性函数。
上面那个式子中,d|n 的意思是在枚举n 的所有约数。证明的话可以使用归纳法,作者将会在后面补上一篇关于上述式子证明的博客,读者也可以尝试自己推导一下。

常见积性函数

1、e(n)=[n=1] .
单位元函数,即只有在n 为1的时候函数值为1,其它时候函数值均为0.

2、id(n)=n .
这个可以理解成就是y=x .

3、1(n)=1 .
可以理解成直线y=1 .

4、φ(n)=∑ n i=1 [gcd(i,n)=1] .
欧拉函数,本次要讲解的主角,表示小于n且与n互质的正整数的个数.

5、μ(n)={ 0, ∃d>1,d 2 |n (−1) k ,n=∏ k i=1 p i
莫比乌斯函数,本文不作探究,详见下一篇博客。

小结

积性函数在数论中十分常见,一个函数假如有积性那么就多了许多解析的方法,在你涉(shua)猎(ti)的数值达到一定量的时候会发现积性是个亲切的东西,比如我们可以利用欧拉函数和莫比乌斯函数的积性来进行线性筛,O(n)时间求得所有欧拉函数、莫比乌斯函数值。

欧拉函数

注:阅读以下内容时请拿出笔和纸,下面涉及的计算量比较大,用笔算一算将助于理解。

概念

正如上一节所述,欧拉函数φ(n) 表示的含义即是小于n且与n互质的正整数的个数。定义式如下:

φ(n)=∑ i=1 n [(gcd(i,n)=1]

基本性质
•1.对于一个质数p,φ(p)=p−1.

证明:根据质数的定义,对于任意一个不是p倍数的正整数x,总有gcd(p,x)=1 ,即p与x互质。在1~p之间,只有1× p是p的倍数,故在1~p中,与p互质的数为1到p-1,共p-1个,φ(p)=p−1 。
•2.对于一个质数p,φ(p k )= p k −p k−1 = p k−1 ×(p−1)= p k−1 ×φ(p) .

证明:我们知道,在1~p之间与p不互质的数共1个,在1~2× p之间与p不互质的数共2个……在1~p k ×p 之间有p k−1 个。所以在1~p k 之间与p不互质的数有p k−1 个,互质的那就是p k −p k−1 ,故φ(p k )= p k −p k−1 ,即第二个式子。然后提取公因数p k−1 得到第三个式子。结合性质1得到第四个式子。
•3.对于一个数n,我们将其质因数分解为n=∏ k i=1 p r i i ,那么
φ(n)= ∏ i=1 k φ(p r i i )= ∏ i=1 k p r i −1 ×(p−1)= n×∏ i=1 k (1−1p i )
.

证明:由于欧拉函数有积性,φ(ab)=φ(a)φ(b) ,所以有φ(n)= ∏ k i=1 φ(p r i i ) 。结合性质2的第三个式子,我们可以得到第三个式子。对于第三个式子,我们提取一个公因子p,得到

∏ i=1 k p r i ×(1−1p i )= (∏ i=1 k p r i )×(∏ i=1 k (1−1p i ))= n×∏ i=1 k (1−1p i ).
得证。

扩展性质
•1.假如a,b不互质,那么φ(ab) 等于什么呢?

结论:令d=gcd(a,b),则φ(ab)= φ(a)φ(b)dφ(d) .

证明:

将a、b、d分解成

a=∏ i=1 m p r 1 i i , b=∏ i=1 m p r 2 i i , d=∏ i=1 m p min(r 1 i, r 2 i) i
那么a×b 可以分解成
a×b=∏ i=1 m p r 1 i+r 2 i i
结合基本性质3,有:
φ(a)=∏ i=1 m φ(p r 1 i i ), φ(b)=∏ i=1 m φ(p r 2 i i ), φ(d)=∏ i=1 m φ(p min(r 1 i, r 2 i) i ),a×b=∏ i=1 m φ(p r 1 i+r 2 i i )

所以,我们将原式转化成如下形式:
∏ i=1 m φ(p r 1 i+r 2 i i )=∏ m i=1 φ(p r 1 i i )×∏ m i=1 φ(p r 2 i i )×∏ m i=1 p min(r 1 i, r 2 i) i ∏ m i=1 φ(p min(r 1 i, r 2 i) i )
结合基本性质3,进一步转化:
左边=∏ i=1 m p r 1 i+r 2 i−1 i (p i −1)

右边=∏ m i=1 p r 1 i−1 i (p i −1)×∏ m i=1 p r 2 i−1 i (p i −1)×∏ m i=1 p min(r 1 i, r 2 i) i ∏ m i=1 p min(r 1 i, r 2 i)−1 i (p i −1)

= ∏ i=1 m p r 1 i−1 i (p i −1)× p r 2 i−1 i (p i −1)× p min(r 1 i, r 2 i) i p min(r 1 i, r 2 i)−1 i (p i −1)

对上面那一长串式子进行约分,我们发现右边等于左边,得证。
•2.对于任意正整数n,φ(n) 与n 有什么样的关系?

结论:n=∑ d|n φ(d).

证明:
我们不妨换个角度思考一下。

我们知道n=∑ n i=1 1 ,如何解读这个简单式子呢?我们把n看成一个确定的数,这个式子就可以理解成:枚举1~n中的每一个数i,每个f(i,n) 只产生1的贡献,统计每个f(n,i) 产生的贡献和。

换句话说,我们本来想统计∑ n i=1 f(n,i) ,但由于每一个f(n,i) 都等于1,所以变成了∑ n i=1 1.

于是,现在的关键变成了寻找这个特殊的f(n,i). 正好我们发现了一个。

我们知道,在1~n中的每一个i,它与n的最大公约数有且仅有一个,且最大公约数一定在1~n这个范围之内。我们可以令f(n,i)=[gcd(n,i)=d] ,([中括号]内的表达式若为真则值为1,否则为0)然后在1~n中枚举最大公约数d,对每一个i进行判断,不就满足上面的式子了!

也就是:

n=∑ i=1 n 1=∑ d=1 n ∑ i=1 n [gcd(n,i)=d].

其中d枚举的是最大公约数,i枚举的是1~n中的每一个i,f(n,i)=[gcd(n,i)=d] 。

其实我们发现,d的取值一定是n的约数,并不需要枚举1~n中的所有数,所以有:

n=∑ d=1 n ∑ i=1 n [gcd(n,i)=d]=∑ d|n ∑ i=1 n [gcd(n,i)=d].

对上面第三个式子进一步转化:

∑ d|n ∑ i=1 n [gcd(n,i)=d]=∑ d|n ∑ i=1 n [gcd(nd ,id )=1]×[ d|i ]

观察上面第二个式子,之所以转化成这么鬼畜的东西是因为第一个式子中[gcd(n,i)=d] 这个式子值为1的时候,d 一定是i 的约数,所以在第二个式子中也必须要满足d 是i 的约数时,[gcd(nd ,id )=1] 才有贡献。

转化到这里,细心的读者估计也发现了,第二个式子中id 的取值范围实际上是1~nd ,所以∑ n i=1 [gcd(nd ,id )=1]×[ d|i ] 其实就是在枚举在1~nd 中,有多少个数与nd 互质,这不就是φ(nd ) 吗?

至此,我们便将原式转化成:

n=∑ d|n ∑ i=1 n [gcd(nd ,id )=1]×[ d|i ]=∑ d|n φ(nd ).

得证。

其实还有一种有趣的证明,我会在后面连同上面积性函数小扩展的证明一同发布一篇博客。

欧拉函数求法
•1.质因数分解.

假如我们只想求解1个或者少量正整数的欧拉函数,那么

根据基本性质3,

φ(n)=n×∏ i=1 k (1−1p i )=n×∏ i=n k (p i −1)p i

我们可以把n质因数分解,然后带入上述第三个式子求得。时间复杂度O(n √ ).

int get_phi(int n){
int back = n;
for(int p = 2; p*p <= n; ++ p){
if(n%p == 0){
back = back/p*(p-1);
while(n%p == 0)
n /= p;
}
}
if(n != 1)
back = back/n*(n-1);

return back;

}1
2
3
4
5
6
7
8
9
10
11
12
13
14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
•2.线性筛

注:默认读者已经掌握线性筛质数.

假如想要求1~n范围内所有数的欧拉函数,那么上面的质因数分解法的复杂度会高达O(nn √ ) ,有没有更快速的方法呢?

由于欧拉函数有积性,所以结合扩展性质1:

令d=gcd(a,b),则φ(ab)= φ(a)φ(b)dφ(d) .

我们可以通过线性筛质数,在筛出合数x×pri j 的同时计算出φ(x×pri j ) 。(注:pri j 为已经筛出来的质数,见线性筛)

不过,需要分2种情况计算:

1.x与pri j 互质.

这种情况比较简单。由于d=1 ,φ(d)=1 ,所以

φ(x×pri j )=φ(x)×φ(pri j )
直接计算即可。

2.x与pri j 不互质.
这种情况下,x 只可能是pri j 的倍数,故d=gcd(x,pri j )=pri j ,所以:

φ(x×pri j )=φ(x)φ(pri j )pri j φ(pri j ) =φ(x)×pri j .

带入计算即可。

bool vis[1000005];
int tot=0, pri[1000005], phi[1000005];

void Get_phi(int N){
phi[1] = 1;
for(int i=2; i<=N; ++i){
if(!vis[i]){
pri[++tot] = i;
phi[i] = i-1;
}
for(int j=1,x; j<=tot&&(x=i*pri[j])<=N; ++j){
vis[x] = true;
if(i%pri[j] == 0){
phi[x] = phi[i]*pri[j];
break;
}
else phi[x] = phi[i]*phi[pri[j]];
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

小结

欧拉函数的讲解就先告一段落,其实欧拉函数与其它的函数甚至定理有许多关联的地方,我将在今后为大家讲解。假如有地方没有听懂,随时欢迎骚扰。

——wrote by miraclejzd

posted @ 2017-08-24 14:38  Drinkwater_cnyali  阅读(1059)  评论(0编辑  收藏  举报