积性函数与筛法

积性函数

定义

积性函数:若一个定义在正整数域上的函数,\(\forall \gcd(x,y)=1, f(xy) = f(x)f(y)\),则称 \(f(x)\) 为积性函数。

常见的积性函数

\(\mu(n)\):莫比乌斯函数

\(\varphi(n)\):欧拉函数

\(\gcd(n,k)\):k为定值

\(d(n)\)\(n\) 的约数个数

\(\sigma(n)\)\(n\) 的约数和

\(\sigma_k(n)\):因子函数,\(n\) 的所有正因子的 \(k\) 次幂之和,当中 \(k\) 可为任何复数。

完全积性函数:若一个定义在正整数域上的函数,\(\forall x,y,f(xy)=f(x)f(y)\),则称 \(f(x)\) 为完全积性函数。

常见的完全积性函数

\(I(n)=1\):不变的函数

\(Id(n)=n\):单位函数

\(Id_k(n)=n^k\):幂函数

\(\epsilon(n)\):若 \(n=1\)\(\epsilon(n)=1\);若 \(n > 1\)\(\epsilon(n)=0\)。别称为“对于狄利克雷卷积的乘法单位”。

狄利克雷卷积

两个积性函数的狄利克雷卷积还是积性函数

狄利克雷卷积:\(F(n) = \sum \limits_{d|n} f(d) g(\frac{n}{d})\)

性质

任意积性函数都可以线性筛。

线性筛

线性筛可以在严格 \(O(n)\) 的时间内筛出积性函数的值。

一些约定

在下文中如无特殊说明,默认 \(p_i\) 表示 \(n\) 质因数分解之后第 \(i\) 个质数,\(a_i\) 表示 \(p_i\) 的指数

线性筛素数

保证每个数只会被它的最小质因子给筛掉,所有线性筛积性函数都必须基于线性筛素数。。

void prime(int n) {
	for (int i = 2; i <= n; ++i) {
		if (!vis[i]) {
			vis[i] = i;
			p[++cnt] = i;
		}
		for (int j = 1; j <= cnt; ++j) {
			if (p[j] > vis[i] || i * p[j] > n) break;
			vis[i * p[j]] = p[j];
		}
	}
}

线性筛莫比乌斯函数

根据莫比乌斯函数的定义:

\[\mu(n) = \begin{cases}1, & n=1 \\(-1)^k, & k为n的本质不同质因子个数 \\0, & n含有平方因子\end{cases} \]

直接筛即可。

void getMu(int n) {
	mu[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if (!vis[i]) p[++cnt] = i, mu[i] = -1;
		for (int j = 1; j <= cnt && i * p[j] <= n; ++j) {
			vis[i * p[j]] = 1;
			if (i % p[j]) mu[i * p[j]] = - mu[i];
			else {
				mu[i * p[j]] = 0;
				break;
			}
		}
	}
}

线性筛欧拉函数

void getPhi(int n) {
	phi[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if (!vis[i]) p[++cnt] = i, phi[i] = i - 1;
		for (int j = 1; j <= cnt && i * p[j] <= n; ++j) {
			vis[i * p[j]] = 1;
			if (i % p[j] == 0) {
				phi[i * p[j]] = phi[i] * p[j];
				break;
			}
			phi[i * p[j]] = phi[i] * phi[p[j]];
		}
	}
}

线性筛约数个数

posted @ 2020-01-20 19:35  newbielyx  阅读(227)  评论(0编辑  收藏  举报