积性函数与筛法
积性函数
定义
积性函数:若一个定义在正整数域上的函数,\(\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]];
}
}
}
线性筛约数个数
既然选择了远方,便只顾风雨兼程。