一堆数学的玩意和补充:欧拉函数、狄利克雷卷积、杜教筛

11490DX Re: Master Lv.15

 

上次讲了莫比乌斯函数和莫比乌斯反演,这次就来补充一下之前没讲到的东西吧。

欧拉函数

定义一个数的欧拉函数 为小于 并且与 的最大公约数为 (即互质)的数的个数。

例如:,因为 均与 互质。

我们在这里探讨一下欧拉函数的性质:

  • 如果 是质数,那么很明显的、

  • 欧拉函数是积性函数,所以当两个数 互质时,

  • 。考虑如何证明。

    假设这里设 。先把所有以 为分母,分子小于等于 的分数列出来。

    然后约分:

    会发现这里的所有分子和分母都是互质的。而这里的分母全部都是 的因数,并且这些因数的所有和这些因数互质的数都做了这些因数的分子。就拿 举例,与 互质的所有数 都在已 为分母的分子上,一共 个互质的数。

    所以可以发现,

    由特殊到一般,对于 的每一个因数 ,和与 互质并 的数 组成的分数 和原来以 为分母的分数 是一一对应的。即可证明。

  • 为质数,那么只有 个数与其不互质,那么

  • 因为每一个数可以被分解为一堆质数的和,设 (其中 为质数),那么因为 一定是互质的,所以

根据最后一个定理,我们就可以使用线性筛 的所有欧拉函数了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int phi[N], prime[N], primecnt;
bool vis[N];
int n;
inline void init(){
vis[1] = phi[1] = 1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[++primecnt] = i;
phi[i] = i-1;
}
for(int j=1;prime[j]*i<=n&&j<=primecnt;j++){
vis[i*prime[j]] = 1;
phi[i*prime[j]] = (i%prime[j]? phi[i]*(prime[j]-1): phi[i]*prime[j]);
if(i%prime[j] == 0) break;
}
}
}

根据这个定理:

可以解决一系列的问题。这种思想和莫比乌斯反演非常相似,这里暂且先把它叫做欧拉反演。

欧拉反演

还是以 举例子:

然后,处理前缀和,整除分块,步骤和莫比乌斯反演一样。

欧拉定理

,则

这个定理经常用于大家都熟悉的费马小定理快速幂求逆元。

狄利克雷卷积

对于两个数论函数(定义域为正整数、值域为复数的函数),定义两个函数的狄利克雷卷积 $(fg)(x)h(x) = (fg)(x)$):

狄利克雷卷积运算满足交换律、结合律和分配律。

而狄利克雷卷积中有三个特殊的函数:

  • 元函数
  • 常数函数
  • 恒等函数

这里列举一些常考的一些函数的卷积关系:

  1. $\mu 1 = \varepsilon\displaystyle \sum_{d\mid n} \mu(d) = [n=1]\mu 1 = \displaystyle\sum_{d\mid x}\mu(d)1(\frac{x}{d}) = \sum_{d\mid x} \mu(d) = [x=1] = \varepsilon$
  2. 。根据欧拉反演:,类似上面的证明即得证。
  3. $\mu id = \varphiid\varphi 1\mu\varphi1 = \mu1\varphi = \varepsilon * \varphi = \varphi$。

注意:定理 3 是莫比乌斯函数和欧拉函数的关系,一定要理解、记住、背过!

根据上面的卷积关系,我们引入一个复杂度为 为积性函数)的一种新算法:杜教筛。

杜教筛

这里令 。我们要求的就是

之前我们学了狄利克雷卷积,而杜教筛就是利用了卷积,先构造积性函数 ,使 能够在非常小的时间复杂度内算出来,然后利用下列递推式递归求出:

考虑这个递推式如何证明:

于是,我们就可以根据之前的 值得出

在做杜教筛时要有几个小技巧:

  1. 首先预处理 (这里的 一般较小,在 左右),只要 ,就直接返回预处理的 值。
  2. 用一个 map 来存储已经算过的 ,记忆化搜索,使其不会重复计算。
  3. 因为其中带了一个 ,所以可以用整除分块做。

现在以一道例题来讲一下杜教筛的应用。

O(n^2/3) 求莫比乌斯函数和欧拉函数前 n 项的和

现在要求 ,那就要构造一个函数 使得 是非常好求的。

回想一下之前的一些常考的卷积关系,里面有一项:,于是就可以令 ,然后带入杜教筛的式子得:

于是就可以预处理 + map 记忆化 + 整除分块来递归求 这种数据规模的值了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const int L = 2e6;
void init(){
...
}
unordered_map<int, int> mob_map;
int getsummob(ll x){
if(x <= L) return summob[x];
if(mob_map.count(x)) return mob_map[x];
ll ans = 1;
for(ll l=2,r;l<=x;l=r+1){
r = (x/(x/l));
ans -= (r-l+1)*getsummob(x/l);
}
mob_map[x] = ans;
return ans;
}

求欧拉函数前缀和也类似,设 ,根据 ,带入杜教筛式子可得:

前面那个等差数列就用求和公式求,后面那个一样用整除分块。

1
2
3
4
5
6
7
8
9
10
11
12
unordered_map<int, ll> phi_map;
ll getsumphi(ll x){
if(x <= L) return sumphi[x];
if(phi_map.count(x)) return phi_map[x];
ll ans = 1ll*(x)*(x+1)/2;
for(ll l=2,r;l<=x;l=r+1){
r = (x/(x/l));
ans -= (r-l+1)*getsumphi(x/l);
}
phi_map[x] = ans;
return ans;
}

其它的杜教筛求前缀和也和这个思想一样,只要构造出好求的 规模在 左右,就可以用杜教筛来求一个积性函数的前缀和。

  • Title: 一堆数学的玩意和补充:欧拉函数、狄利克雷卷积、杜教筛
  • Author: 11490DX
  • Created at : 2025-01-02 15:17:04
  • Updated at : 2025-02-14 13:09:58
  • Link: https://11490dx.net/2025/01/02/eulerfunc-etc/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
一堆数学的玩意和补充:欧拉函数、狄利克雷卷积、杜教筛