数论函数小记

摘自 command_block 大佬的笔记

基础:

  • 积性函数:若当 \((i,j) = 1\)\(f(i \times j) = f(i) \times f(j)\),则称 \(f\) 为积性函数。

  • 完全积性函数:若当 \(f(i \times j) = f(i) \times f(j)\) , 则称 \(f\) 为完全积性函数。

  • \(I(n)\) : 值恒为 1 的函数。

  • \(e(n)\) : 当 \(n = 1\) 时值为 1,否则为 0 。

  • \(id(n)\)\(id(n) = n\)

  • tips:这些都为完全积性函数。

狄利克雷卷积:

给定两个数论函数 \(f, g\) ,则这两个函数的狄利克雷卷积 \((f * g)\) 定义为:

\[(f * g) (n) = \sum_{d | n} f(d)g(\frac{n}{d}) \]

特殊的, 我们一个函数 \(f\) 的逆 \(f^{-1}\) 定义为: \(f * f^{-1} = e\)

莫比乌斯函数:

  • 引理 1:

    若两个函数 \(f,g\) 的卷积为积性函数,且 \(g\) 为积性函数,则 \(f\) 也是积性函数

我们定义 \(\mu\) 为一个逆为 \(I\)积性函数,既满足 \(\mu * I = e\),接下来我们推一下它的定义。

显然 \(\mu(1) = 1\)

  • tips: 观察一个积性函数,可以先从 \(p^k\) 的情形入手。

\(\mu(p^k):\)\(k = 0\) 时,函数值为 1。

由卷积的定义得: \(\mu(p^k) = \mu(p^k) + \mu(p^{k-1}) + ... + \mu(p^0)\)

即为: \(\mu(p^k) + \mu(p^{k-1}) + ... + \mu(p^0) = 0\)

又因为 \(\mu\)积性函数,所以 \(\mu(n) = \prod _{i = 1}^{cntp} \mu(p_i^{c_i})\)

则可以得到 \(\mu\) 的定义了:

\(n\) 有一个次数大于一的质因子时,\(\mu(n) = 0\)

否则 \(\mu(n) = (-1)^ {cntp}\).

一些常见的结论:

  • 卷积式:

    \(\mu * I = e\)

    $ I * \varphi = id$ 即 \(id * \mu = \varphi\)

    \(d = I * I\) (\(d\) 是一个数的约数个数)

    \(F = f * I\)\(f = \mu * F\) (重要!!)

  • 函数运算:

    \(\mu(ij) = \mu(i)\mu(j)[i⊥j]\)

    \(d(ij) = \sum _{x | i}\sum_{y | j} [x⊥y]\)

    \(\sum ^ n _ {i = 1} d(i) = \sum ^ n _{i = 1} \lfloor \frac{n}{i} \rfloor\)

莫比乌斯反演:

十分灵活,主要基于上面的柿子和一些奇怪结论。

看一道例题 P2257 YY的GCD

题目就是让你求:

\[\sum_{i = 1} ^ n \sum_{j = 1} ^ m [(i,j) = prime] \]

\[=\sum ^{n}_{p \in prime} \sum_{i = 1} ^ n \sum_{j = 1} ^ m [(i,j) = p] \]

(看起来很废话,但是也是重要的)

\(i, j\) 都除掉 \(p\):

\[\sum ^{n}_{p \in prime} \sum_{i = 1} ^ {n / p} \sum_{j = 1} ^ {m / p} [(i,j) = 1] \]

代入 \(\mu * I = e\)

\[\sum ^{n}_{p \in prime} \sum_{i = 1} ^ {n / p} \sum_{j = 1} ^ {m / p} \sum_{d = 1} ^ {m / p}\mu(d) [d | i][d | j] \]

\(\mu\) 提到前面:

\[\sum ^{n}_{p \in prime} \sum_{d = 1} ^ {m / p}\mu(d)\sum_{i = 1} ^ {n / p} \sum_{j = 1} ^ {m / p} [d | i][d | j] \]

整理一下:

\[\sum ^{n}_{p \in prime} \sum_{d = 1} ^ {m / p}\mu(d) \lfloor \frac{n}{dp}\rfloor \lfloor \frac{m}{dp} \rfloor \]

  • tips: 遇到乘积式需要考虑代换掉并变为整除形式。

还是不好做,发现 \(dp\) 为乘积式很不好,令 \(k = dp\)

\[\sum_{k = 1} ^ {n}\sum ^{}_{p \in prime 且 p | k}\mu(\frac{k}{p}) \lfloor \frac{n}{k}\rfloor \lfloor \frac{m}{k} \rfloor \]

  • tips: 发现求和式性质不明显时,可以考虑交换枚举变量或交换求和式顺序。

注意到这个柿子只有 \(\mu\) 项与 \(p\) 相关,于是交换求和式顺序。

\[\sum_{k = 1} ^ {n} \lfloor \frac{n}{k}\rfloor \lfloor \frac{m}{k} \rfloor \sum ^{}_{p \in prime 且 p | k}\mu(\frac{k}{p}) \]

\(f(x)\) 为后面那一坨柿子,用埃氏筛即可预处理出来。

接着使用整除分块技巧计算前面的柿子即可。

code:

#include<bits/stdc++.h>
#define int long long 
using namespace std;

const int N = 1e7 + 10;
int prime[N], tot, mu[N], g[N];
bool isprime[N];

void init(){
	for(int i = 2; i < N; i++) isprime[i] = true;
	isprime[1] = false, mu[1] = 1;
	for(int i = 2; i < N; i++){
		if(isprime[i]) prime[++tot] = i, mu[i] = -1;
		for(int j = 1; j <= tot && i * prime[j] < N; j++){
			isprime[i * prime[j]] = false;
			if(i % prime[j] == 0) break;
			mu[i * prime[j]] = -mu[i]; 
		}
	}
	for(int i = 1; i <= tot; i++){
		for(int j = prime[i]; j < N; j += prime[i]){
			g[j] += mu[j / prime[i]];
		}
	}
	for(int i = 2; i < N; i++) g[i] += g[i - 1];
}

int H(int n, int m){
	int ret = 0, l = 1, r, siz = min(n, m);
	while(l <= siz){
		r = min(siz, min(n / (n / l), m / (m / l)));
		ret += (g[r] - g[l - 1]) * (n / l) * (m / l);
		l = r + 1;
	}
	return ret;
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	init(); int T; cin >> T;
	while(T--){
		int n, m; 
		cin >> n >> m;
		cout << H(n, m) << "\n";
	}
	
	return 0;
}

还有另一种反演形式:

\(\sum^{n}_{i = 1} \sum^{m}_{j=1}f(\gcd(i,j))\)

向上面一样的推法可以得出这个柿子等于:

\(\sum^{n}_{x=1} \lfloor \frac{n}{x}\rfloor\lfloor \frac{m}{x}\rfloor\sum_{d|x} \mu(d)f(\frac{x}{d})\)

\(f\) 是积性函数,则可以欧拉筛,否则埃氏筛即可。

例题:P3312 [SDOI2014] 数表

杜教筛:

杜教筛是一种高效计算一类数论函数前缀和的筛法。

杜教筛的核心是构造两个合适的数论函数,使得 \(h = f * g\)\(f\) 为待求函数),而且 \(h, g\) 的前缀和易求。

杜教筛公式:

我们令 \(S(n) = \sum_{i = 1} ^ n f(i)\)

于是有:

\[\sum_{i = 1} ^ n h(i) = \sum _{i = 1} ^n \sum _{d | i} g(d)f(\frac{i}{d}) \]

做一个小小的变换得到:

\[\sum_{i = 1}^{n}h(i)= \sum_{d=1}^ng(d)\sum_{d|i}^{n}f(\frac{i}{d}) \]

进行化简:

\[\sum^n_{i = 1}h(i) = \sum_{d = 1}^ng(d)\sum{}_{i = 1} ^ {\lfloor \frac{n}{d}\rfloor}f(i) \]

整理后有:

\[\sum^n_{i = 1}h(i) = \sum_{d = 1}^ng(d)S(\lfloor \frac{n}{d}\rfloor) \]

\(S(n)\) 拆出来:

\[g(1)S(n) = \sum_{i = 1}^{n}h(i) - \sum_{i = 2}^{n}g(i)S(\lfloor \frac{n}{i} \rfloor) \]

这就是杜教筛公式了。

实现:

首先我们算出 \(\sqrt n\)\(f\) 的前缀和。

对于一个 \(S(n)\),我们对它做整除分块并递归计算 \(S(\lfloor \frac{n}{l} \rfloor)\)

可以证明时间复杂度为 \(O(n ^{\frac{2}{3}})\)(然而我太菜了并不会呜呜呜)。

例题

posted @ 2024-04-25 13:25  Little_corn  阅读(4)  评论(0编辑  收藏  举报