[关闭]
@computerkiller 2021-03-25T08:04:17.000000Z 字数 2920 阅读 1048

Dirichlet生成函数

数学


对于一些奇怪的数论问题有奇效。也是对数论函数的另一种视角。

基础形式

数列 的狄利克雷生成函数是

容易验证它的乘积就是狄利克雷卷积

狄利克雷函数初看非常的诡异,它和普通型与指数型不同,并不是一个形式幂级数。我们介绍一些典型的狄利克雷生成函数来了解它的性质。

典型函数

过于显然地 ,也就是数论中的 函数,的狄利克雷生成函数是 1。

zeta 函数

众所周知研究某型生成函数都要从 开始,也就是数论中的 函数,它的狄利克雷生成函数是

你可能已经在各种科普文上见过这个函数。这就是著名的黎曼 函数。

和 以及 不同,它的性质比较复杂,我们甚至不完全了解它的零点……不过这和接下来的介绍关系不大。

是一个(完全)积性函数,把 分解质因数后每个 对它的贡献是独立的,也就是说有下面的形式

这个形式会极大地方便我们讨论积性函数的性质。比如


那么它的逆就是

莫比乌斯函数

当 时贡献为 ,当 时贡献为 ,否则贡献为 ,正是莫比乌斯函数 。也就是说

ID 函数

显然就是

同理,

约数个数和

显然有

欧拉函数

有

从中可以立刻看出欧拉函数的筛法:

也就是说, 的贡献是

当质因数增加了一个 的时候按这个柿子更新贡献即可。

实际应用

例一

筛出 。

解答

它就是 ,容易知道 的贡献是

运算

我们继续来研究一下 DGF 的各种运算

下面我们讨论的 默认:

乘法

考虑:


直接卷 可以做到

高妙的高维前缀和可以做到 这里放板子题

求逆

事实上我们是要构造一个 满足:


按照多项式求逆的套路写:

一样倍增处理就好了qaq

复杂度是

积分和求导

先考虑求导好了 积分就是逆过程

求导的式子是:


我们重新定义 定义: 的可重质因子数

我们记我们定义的这个函数是

那么显然有

愉快地可以进行求导了 积分就是这个的逆过程 不多说了

取对数

直接快进到:


复杂度显然的

exp

性质还好:


提取系数:

和求逆一样倍增就好了

这堆板子看着就很好写 来一个:

  1. void derivation(int *f,int len,int *g)
  2. {
  3. for (int i = 1; i <= len; i++) g[i] = f[i] * c[i] % mod;
  4. }
  5. void integration(int *f,int len,int *g)
  6. {
  7. g[1] = f[1];
  8. for (int i = 2; i <= len; i++) g[i] = f[i] * inv[c[i]] % mod;
  9. }
  10. void mul(int *f,int *g,int len,int *h)
  11. {
  12. for (int i = 1; i <= len; i++)
  13. for (int j = 1; i * j <= len; j++)
  14. h[i * j] = (h[i * j] + f[i] * g[j]) % mod;
  15. }
  16. void getinv(int *f,int len,int *g)
  17. {
  18. g[1] = 1;
  19. for (int i = 1; i <= len; i++)
  20. for (int j = 2; i * j <= len; j++)
  21. g[i * j] = (g[i * j] - g[i] * f[j] % mod + mod) % mod;
  22. }
  23. void getln(int *f,int len,int *g)
  24. {
  25. derivation(f,len,A);
  26. getinv(f,len,B);
  27. mul(A,B,len,C);
  28. integration(C,len,g);
  29. for (int i = 1; i <= len; i++)
  30. A[i] = B[i] = C[i] = 0;
  31. }
  32. void getexp(int *f,int len,int *g)
  33. {
  34. derivation(f,len,A);
  35. g[1] = 1;
  36. for (int i = 1; i <= len; i++)
  37. {
  38. if (i > 1) g[i] = g[i] * inv[c[i]] % mod;
  39. for (int j = 2; i * j <= len; j++)
  40. g[i * j] = (g[i * j] + g[i] * A[j]) % mod;
  41. }
  42. for (int i = 1; i <= len; i++)
  43. A[i] = 0;
  44. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注