积性函数
若 gcd ( x , y ) = 1 \gcd(x,y)=1 gcd(x,y)=1 且 f ( x y ) = f ( x ) f ( y ) f(x y)=f(x) f(y) f(xy)=f(x)f(y) ,则 f ( n ) f(n) f(n) 为积性函数。
狄利克雷卷积
定义两个数论函数 f , g f,g f,g 的狄利克雷卷积为
( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) ∗ ≠ × (f \ast g)(n)=\sum_{d\mid n}f(d)g(\frac{n}{d}) \\ \ast \not= \times (f∗g)(n)=d∣n∑f(d)g(dn)∗=×
狄利克雷卷积卷积满足交换律、结合律、单位元,逆元。其中单位元符号为 ϵ \epsilon ϵ。
ϵ ( n ) = [ n = 1 ] \epsilon(n) = [n = 1] ϵ(n)=[n=1]
当 n = 1 n=1 n=1 时 ϵ ( n ) = 1 \epsilon (n) = 1 ϵ(n)=1,否则为 0 0 0。
莫比乌斯函数
莫比乌斯函数也是积性函数, μ \mu μ 为莫比乌斯函数的符号
μ ( n ) = { 1 n = 1 0 n = ⌊ n ⌋ 2 ( − 1 ) k n = ∏ i = 1 k p i \mu(n)= \begin{cases} 1&n=1\\ 0&n = \left\lfloor \sqrt{n} \right\rfloor ^2\\ (-1)^k& n = \prod_{i=1}^k p_i \end{cases} μ(n)=⎩⎪⎨⎪⎧10(−1)kn=1n=⌊n⌋2n=∏i=1kpi
莫比乌斯函数,不变函数,狄利克雷卷积单位元有一个重要的性质。其中不变函数为积性函数, 1 ( n ) = 1 1(n) = 1 1(n)=1。莫比乌斯函数的逆元就是不变函数,即为
μ ∗ 1 = ε \mu * 1 =\varepsilon μ∗1=ε
略证:设 n n n 不同的质因子个数为 k k k,则有
μ ∗ 1 = ∑ d ∣ n μ ( d ) = ∑ i = 0 k ( − 1 ) i × C i k \mu \ast 1 = \sum_{d|n} \mu(d) = \sum_{i=0}^k (-1)^i \times C_{i}^k μ∗1=d∣n∑μ(d)=i=0∑k(−1)i×Cik
由二项式定理得
( x + y ) k = ∑ i = 0 k x i y k − i × C i k (x + y)^k = \sum_{i=0}^k x^i y^{k-i} \times C_i^k (x+y)k=i=0∑kxiyk−i×Cik
令 x = − 1 , y = 1 x=-1,y=1 x=−1,y=1,代入得
0 k = ∑ i = 1 k ( − 1 ) i × C i k 0^k = \sum_{i=1}^k (-1)^i \times C_{i}^k 0k=i=1∑k(−1)i×Cik
因为只有 1 1 1 的质因子数 k = 0 k = 0 k=0,而 0 0 = 1 0^0 = 1 00=1,其他情况为 1 1 1,这正是狄利克雷卷积单位元的定义,即为
μ ∗ 1 = ϵ \mu \ast 1 = \epsilon μ∗1=ϵ
线性筛
线性筛即为欧拉筛,因为 μ \mu μ 是积性函数,所以可以线性筛莫比乌斯函数。
void init() {
mu[1] = 1;
for (int i = 2; i <= n; i++) {
if (!vis[i]) pr[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * pr[j] <= n; j++) {
vis[i * pr[j]] = 1;
if (i % pr[j] == 0) {
mu[i * pr[j]] = 0;
break;
}
mu[i * pr[j]] = -mu[i];
}
}
}
数论分块
对于任意一个块的左端点
i
(
i
≤
n
)
i \quad (i\leq n)
i(i≤n) ,需要找到块的右端点
j
(
i
≤
j
≤
n
)
j \quad (i\leq j\leq n)
j(i≤j≤n) 使得
⌊
n
i
⌋
=
⌊
n
j
⌋
\left \lfloor\frac{n}{i}\right\rfloor = \left\lfloor\frac{n}{j} \right \rfloor
⌊in⌋=⌊jn⌋
若能求出
j
j
j,那么下一个块的
i
=
j
+
1
i = j + 1
i=j+1。
令 ⌊ n i ⌋ = k \large \left \lfloor \frac{n}{i} \right \rfloor = k ⌊in⌋=k,有 i × k + p = n \large i \times k + p = n i×k+p=n。其中 p = n m o d i \large p = n \mod i p=nmodi。
将
n
j
=
k
\large \frac{n}{j} = k
jn=k 表示为
n
i
+
d
m
a
x
=
k
\large \frac{n}{i + d_{max}} = k
i+dmaxn=k。对于
n
i
+
d
=
k
\large \frac{n}{i + d} = k
i+dn=k,同上有
(
i
+
d
)
×
k
+
p
′
=
n
(i+d) \times k + p'=n
(i+d)×k+p′=n。有
(
i
+
d
)
×
k
+
p
′
=
i
×
k
+
p
=
n
(i+d) \times k + p' = \large i \times k + p = n
(i+d)×k+p′=i×k+p=n
p ′ = i × k + p − i × k − d × k = p − d × k p' = i \times k + p - i \times k - d \times k = p - d \times k p′=i×k+p−i×k−d×k=p−d×k
因为 p ′ ≥ 0 p' \ge 0 p′≥0 且 d d d 为整数,所以有 p − d × k ≥ 0 p - d \times k \ge 0 p−d×k≥0,进而推出 d m a x = ⌊ p k ⌋ d_{max} = \left \lfloor \frac{p}{k} \right \rfloor dmax=⌊kp⌋
推式子
j
=
i
+
d
m
a
x
=
i
+
⌊
p
k
⌋
j = i + d_{max} = i + \left \lfloor \frac{p}{k} \right \rfloor
j=i+dmax=i+⌊kp⌋
= i + ⌊ n m o d i ⌊ n i ⌋ ⌋ = ⌊ i + n m o d i ⌊ n i ⌋ ⌋ = i+ \left \lfloor \frac{n \mod i}{\left \lfloor \frac{n}{i} \right \rfloor} \right \rfloor = \left \lfloor i +\frac{n \mod i}{\left \lfloor \frac{n}{i} \right \rfloor} \right \rfloor =i+⌊⌊in⌋nmodi⌋=⌊i+⌊in⌋nmodi⌋
= ⌊ i + n − ⌊ n i ⌋ × i ⌊ n i ⌋ ⌋ = \left \lfloor i+ \frac{n - \left \lfloor \frac{n}{i} \right \rfloor \times i}{ \left \lfloor \frac{n}{i} \right \rfloor} \right \rfloor =⌊i+⌊in⌋n−⌊in⌋×i⌋
= ⌊ ⌊ n i ⌋ × i ⌊ n i ⌋ + n − ⌊ n i ⌋ × i ⌊ n i ⌋ ⌋ = \left \lfloor \frac{\left \lfloor \frac{n}{i}\right \rfloor \times i}{\left \lfloor \frac{n}{i} \right \rfloor }+ \frac{n - \left \lfloor \frac{n}{i} \right \rfloor \times i}{ \left \lfloor \frac{n}{i} \right \rfloor} \right \rfloor =⌊⌊in⌋⌊in⌋×i+⌊in⌋n−⌊in⌋×i⌋
= ⌊ n − ⌊ n i ⌋ × i + ⌊ n i ⌋ × i ⌊ n i ⌋ ⌋ = \left \lfloor \frac{n - \left \lfloor \frac{n}{i} \right \rfloor \times i + \left \lfloor \frac{n}{i} \right \rfloor \times i}{ \left \lfloor \frac{n}{i} \right \rfloor} \right \rfloor =⌊⌊in⌋n−⌊in⌋×i+⌊in⌋×i⌋
= ⌊ n ⌊ n i ⌋ ⌋ = \left \lfloor \frac{n}{ \left \lfloor \frac{n}{i} \right \rfloor} \right \rfloor =⌊⌊in⌋n⌋
所以 j = ⌊ n ⌊ n i ⌋ ⌋ j = \left \lfloor \frac{n}{ \left \lfloor \frac{n}{i} \right \rfloor} \right \rfloor j=⌊⌊in⌋n⌋。
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
ans += (r - l + 1) * (n / l);
}
莫比乌斯反演
对于数论函数 f , g f,g f,g。
如果有
f ( n ) = ∑ d ∣ n g ( d ) f(n)=\sum_{d\mid n}g(d) f(n)=d∣n∑g(d)
那么有
g ( n ) = ∑ d ∣ n μ ( d ) f ( n d ) g(n)=\sum_{d\mid n}\mu(d)f(\frac{n}{d}) g(n)=d∣n∑μ(d)f(dn)
略证:上述结论可以转换为,已知 f = g ∗ 1 f = g \ast 1 f=g∗1,证明 g = f ∗ μ g = f \ast \mu g=f∗μ。
f ∗ μ = g ∗ 1 ∗ μ ∵ μ ∗ 1 = ϵ ∴ f ∗ μ = g f \ast \mu = g \ast 1 \ast \mu \\ \because \mu \ast 1 = \epsilon \\ \therefore f \ast \mu = g f∗μ=g∗1∗μ∵μ∗1=ϵ∴f∗μ=g
推论
[ g c d ( i , j ) = 1 ] = ∑ d ∣ g c d ( i , j ) μ ( d ) [gcd(i,j)=1] = \sum_{d|gcd(i,j)} \mu(d) [gcd(i,j)=1]=d∣gcd(i,j)∑μ(d)
栗子
求
∑ i = 1 n ∑ j = 1 m [ gcd ( i , j ) = k ] \sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)=k] i=1∑nj=1∑m[gcd(i,j)=k]
化简该式子
∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ m k ⌋ [ gcd ( i , j ) = 1 ] \sum_{i=1}^{\left\lfloor\frac{n}{k}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{k}\right\rfloor}[\gcd(i,j)=1] i=1∑⌊kn⌋j=1∑⌊km⌋[gcd(i,j)=1]
换掉 [ g c d ( i , j ) ] = 1 [gcd(i,j)]=1 [gcd(i,j)]=1
∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ m k ⌋ ∑ d ∣ gcd ( i , j ) μ ( d ) \sum_{i=1}^{\left\lfloor\frac{n}{k}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{k}\right\rfloor}\sum_{d\mid \gcd(i,j)}\mu(d) i=1∑⌊kn⌋j=1∑⌊km⌋d∣gcd(i,j)∑μ(d)
枚举 d d d,那么 i i i 和 j j j 都是 d d d 的倍数。而 1 ∼ ⌊ n k ⌋ 1\sim\left\lfloor\dfrac{n}{k}\right\rfloor 1∼⌊kn⌋ 中 d d d 的倍数有 ⌊ n k d ⌋ \left\lfloor\dfrac{n}{kd}\right\rfloor ⌊kdn⌋ 个
∑ d = 1 μ ( d ) ⌊ n k d ⌋ ⌊ m k d ⌋ \sum_{d=1}\mu(d)\left\lfloor\frac{n}{kd}\right\rfloor\left\lfloor\frac{m}{kd}\right\rfloor d=1∑μ(d)⌊kdn⌋⌊kdm⌋
筛出 μ \mu μ,数论分块求 ∑ d = 1 ⌊ n k d ⌋ ⌊ m k d ⌋ \sum_{d=1}\left\lfloor\frac{n}{kd}\right\rfloor\left\lfloor\frac{m}{kd}\right\rfloor ∑d=1⌊kdn⌋⌊kdm⌋。
#include <bits/stdc++.h>
using namespace std;
#define re register
#define F first
#define S second
typedef long long ll;
typedef pair<int, int> P;
const int N = 1e6 + 5;
const int INF = 0x3f3f3f3f;
inline int read() {
int X = 0,w = 0; char ch = 0;
while(!isdigit(ch)) {w |= ch == '-';ch = getchar();}
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48),ch = getchar();
return w ? -X : X;
}
int cnt;
int p[N], vis[N];
ll mu[N];
void init(){
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] == 0){
mu[i * p[j]] = 0;
break;
}
mu[i * p[j]] = -mu[i];
}
}
for (int i = 1; i <= N; i++) mu[i] += mu[i - 1];
}
ll solve(int n, int m){
ll ans = 0;
for (int i = 1, j; i <= min(n, m); i = j + 1){
j = min(n / (n / i), m / (m / i));
ans += 1ll * (mu[j] - mu[i - 1]) * (n / i) * (m / i);
}
return ans;
}
int main(){
init();
int n = read(), m = read(), k = read();
printf("%lld\n", solve(n / k, m / k));
return 0;
}