一、莫比乌斯函数
μ
(
n
)
=
{
1
n
=
1
0
n
含有平方因子
(
−
1
)
k
k
为
n
的本质不同质因子个数
\mu(n) = \begin{cases} 1 & n = 1 \\ 0 & n \text{含有平方因子} \\ (-1)^k & k \text{为}n \text{的本质不同质因子个数} \end{cases}
μ(n)=⎩
⎨
⎧10(−1)kn=1n含有平方因子k为n的本质不同质因子个数
性质:
∑
d
∣
n
μ
(
d
)
=
{
1
n
=
1
0
n
≠
1
\sum_{d|n}\mu(d) = \begin{cases} 1 & n = 1 \\ 0 & n \ne 1 \end{cases}
d∣n∑μ(d)={10n=1n=1
证明:
∀ n ∈ Z \forall n\in \mathbb{Z} ∀n∈Z,通过唯一分解定理得: n = p 1 α 1 p 2 α 2 … p k α k n=p_1^{\alpha_1}p_2^{\alpha_2}\dots p_k^{\alpha_k} n=p1α1p2α2…pkαk
∀ d ∣ n \forall d|n ∀d∣n,通过唯一分解定理得: d = p 1 β 1 p 2 β 2 … p k β k d=p_1^{\beta_1}p_2^{\beta_2}\dots p_k^{\beta_k} d=p1β1p2β2…pkβk, β i ∈ [ 0 , α i ] \beta_i\in [0,\alpha_i] βi∈[0,αi]
若 ∃ i , β i ≥ 2 \exist i,\beta_i\ge 2 ∃i,βi≥2,那么由莫比乌斯函数的定义得,这个 d d d 对于和没有贡献。
反之, ∀ i , β i ≤ 1 \forall i,\beta_i\le 1 ∀i,βi≤1,记 m m m 为 β i = 1 \beta_i=1 βi=1 的 i i i 的个数,那么 ∑ d ∣ n μ ( d ) = ∑ d ∣ n ( − 1 ) m = ∑ i = 0 k C k i ( − 1 ) i \sum_{d|n}\mu(d)=\sum_{d|n}(-1)^m=\sum_{i=0}^k C_k^i (-1)^i ∑d∣nμ(d)=∑d∣n(−1)m=∑i=0kCki(−1)i
解释:从 k k k 个数中选出 i i i 个 β j = 1 , j ∈ [ 1 , k ] \beta_j=1,j\in[1,k] βj=1,j∈[1,k],方案数为 C k i C_k^i Cki,贡献为 ( − 1 ) i (-1)^i (−1)i。
观察发现为二项式定理,故: ∑ i = 0 k C k i ( − 1 ) i = ( 1 + ( − 1 ) ) k = 0 \sum_{i=0}^k C_k^i (-1)^i=(1+(-1))^k=0 ∑i=0kCki(−1)i=(1+(−1))k=0
所以,只有 n = 1 n=1 n=1 的时候, ∑ d ∣ n μ ( d ) = 1 \sum_{d|n}\mu(d)=1 ∑d∣nμ(d)=1,证毕。
二、莫比乌斯反演
若有 F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum_{d|n}f(d) F(n)=∑d∣nf(d),那么有 f ( n ) = ∑ d ∣ n μ ( d ) F ( n d ) f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d}) f(n)=∑d∣nμ(d)F(dn)
若有 F ( n ) = ∑ n ∣ d f ( d ) F(n)=\sum_{n|d}f(d) F(n)=∑n∣df(d),那么有 f ( n ) = ∑ n ∣ d μ ( d n ) F ( d ) f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d) f(n)=∑n∣dμ(nd)F(d)
其中实际应用通常使用②式,且 F F F 好求,而 f f f 不好求,但是满足条件,所以可以通过 F F F 来求解 f f f。
一式证明:
∑
d
∣
n
μ
(
d
)
∑
i
∣
n
d
f
(
i
)
=
∑
d
∣
n
f
(
i
)
∑
d
∣
n
i
μ
(
d
)
→
∑
d
∣
n
i
μ
(
d
)
=
1
当且仅当
i
为
n
=
f
(
n
)
\begin{align*} &&&\sum_{d|n}\mu(d)\sum_{i|\frac{n}{d}}f(i)\\ &=&&\sum_{d|n}f(i)\sum_{d|\frac{n}{i}}\mu(d)\rightarrow \sum_{d|\frac{n}{i}}\mu(d)=1当且仅当\ i\ 为\ n\\ &=&&f(n) \end{align*}
==d∣n∑μ(d)i∣dn∑f(i)d∣n∑f(i)d∣in∑μ(d)→d∣in∑μ(d)=1当且仅当 i 为 nf(n)
二式证明:
∑
n
∣
d
μ
(
d
n
)
F
(
d
)
=
∑
n
∣
d
μ
(
n
d
)
∑
d
∣
i
f
(
i
)
=
∑
n
∣
i
f
(
i
)
∑
d
′
∣
i
n
μ
(
d
′
)
→
d
′
=
n
d
=
f
(
n
)
\begin{align*} \sum_{n|d}\mu(\frac{d}{n})F(d) =& \sum_{n|d}\mu(\frac{n}{d})\sum_{d|i}f(i)\\ =&\sum_{n|i}f(i) \sum_{d'|\frac{i}{n}}\mu(d')\rightarrow d'=\frac{n}{d}\\ =& f(n) \end{align*}
n∣d∑μ(nd)F(d)===n∣d∑μ(dn)d∣i∑f(i)n∣i∑f(i)d′∣ni∑μ(d′)→d′=dnf(n)
三、例题精讲
对于给出的 n n n 个询问,每次求有多少个数对 ( x , y ) (x,y) (x,y),满足 a ≤ x ≤ b a \le x \le b a≤x≤b, c ≤ y ≤ d c \le y \le d c≤y≤d,且 gcd ( x , y ) = k \gcd(x,y) = k gcd(x,y)=k, gcd ( x , y ) \gcd(x,y) gcd(x,y) 函数为 x x x 和 y y y 的最大公约数。
1 ≤ n , k ≤ 5 × 1 0 4 1 \le n,k \le 5 \times 10^4 1≤n,k≤5×104, 1 ≤ a ≤ b ≤ 5 × 1 0 4 1 \le a \le b \le 5 \times 10^4 1≤a≤b≤5×104, 1 ≤ c ≤ d ≤ 5 × 1 0 4 1 \le c \le d \le 5 \times 10^4 1≤c≤d≤5×104。
将数对 ( x , y ) (x,y) (x,y) 映射成平面直角坐标系中的一个点,那么对于每一次查询相当于在左下角为 ( a , c ) (a,c) (a,c),右上角为 ( b , d ) (b,d) (b,d) 的矩形内查询有多少个点 ( x , y ) (x,y) (x,y) 满足 gcd ( x , y ) = k \gcd(x,y)=k gcd(x,y)=k。
那么,通过差分可以将问题简化为求左下角 ( 0 , 0 ) (0,0) (0,0),右上角为 ( a , b ) (a,b) (a,b) 的矩形内查询有多少个点 ( x , y ) (x,y) (x,y) 满足 gcd ( x , y ) = k \gcd(x,y)=k gcd(x,y)=k。
考虑如何设计 F ( n ) F(n) F(n) 与 f ( n ) f(n) f(n),由于为了 F F F 好求,所以设 F ( n ) = ∑ x , y [ n ∣ gcd ( x , y ) ] F(n)=\sum_{x,y}[n|\gcd(x,y)] F(n)=∑x,y[n∣gcd(x,y)],由于要满足约数和的关系,所以设 f ( n ) = ∑ x , y [ gcd ( x , y ) = n ] f(n)=\sum_{x,y}[\gcd(x,y)=n] f(n)=∑x,y[gcd(x,y)=n]。
那么,观察可以发现, F ( n ) = ∑ n ∣ d f ( d ) F(n)=\sum_{n|d}f(d) F(n)=∑n∣df(d)。所以,可以套用莫比乌斯反演得: f ( n ) = ∑ n ∣ d μ ( n d ) F ( d ) f(n)=\sum_{n|d}\mu(\frac{n}{d})F(d) f(n)=∑n∣dμ(dn)F(d)
那么,考虑如何求解
F
(
n
)
F(n)
F(n):
F
(
n
)
=
∑
x
=
1
a
∑
y
=
1
b
[
n
∣
gcd
(
x
,
y
)
]
=
∑
x
=
1
a
∑
y
=
1
b
[
n
∣
x
,
n
∣
y
]
=
⌊
a
n
⌋
⌊
b
n
⌋
\begin{align*} F(n)=&\sum_{x=1}^a\sum_{y=1}^b[n|\gcd(x,y)]\\ =&\sum_{x=1}^a\sum_{y=1}^b[n|x,n|y]\\ =&\lfloor\frac{a}{n}\rfloor\lfloor\frac{b}{n}\rfloor \end{align*}
F(n)===x=1∑ay=1∑b[n∣gcd(x,y)]x=1∑ay=1∑b[n∣x,n∣y]⌊na⌋⌊nb⌋
则:
f
(
n
)
=
∑
n
∣
d
μ
(
n
d
)
⌊
a
d
⌋
⌊
b
d
⌋
f(n)=\sum_{n|d}\mu(\frac{n}{d})\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor
f(n)=∑n∣dμ(dn)⌊da⌋⌊db⌋
继续化简方便求解(尽量化成区间的和):
f
(
n
)
=
∑
n
∣
d
μ
(
n
d
)
⌊
a
d
⌋
⌊
b
d
⌋
=
∑
d
′
∈
Z
μ
(
d
′
)
⌊
a
d
′
n
⌋
⌊
b
d
′
n
⌋
→
d
′
=
n
d
=
∑
d
′
∈
Z
μ
(
d
′
)
⌊
a
′
d
′
⌋
⌊
b
′
d
′
⌋
→
a
′
=
⌊
a
n
⌋
,
b
′
=
⌊
b
n
⌋
\begin{align*} f(n)=&\sum_{n|d}\mu(\frac{n}{d})\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\\ =&\sum_{d'\in \mathbb{Z}}\mu(d')\lfloor\frac{a}{d'n}\rfloor\lfloor\frac{b}{d'n}\rfloor\rightarrow d'=\frac{n}{d}\\ =&\sum_{d'\in \mathbb{Z}}\mu(d')\lfloor\frac{a'}{d'}\rfloor\lfloor\frac{b'}{d'}\rfloor\rightarrow a'=\lfloor\frac{a}{n}\rfloor,b'=\lfloor\frac{b}{n}\rfloor \end{align*}
f(n)===n∣d∑μ(dn)⌊da⌋⌊db⌋d′∈Z∑μ(d′)⌊d′na⌋⌊d′nb⌋→d′=dnd′∈Z∑μ(d′)⌊d′a′⌋⌊d′b′⌋→a′=⌊na⌋,b′=⌊nb⌋
疑难解答
为什么 ⌊ a d ′ n ⌋ = ⌊ a ′ d ′ ⌋ = ⌊ ⌊ a n ⌋ d ′ ⌋ \lfloor\frac{a}{d'n}\rfloor=\lfloor\frac{a'}{d'}\rfloor=\lfloor\frac{\lfloor\frac{a}{n}\rfloor}{d'}\rfloor ⌊d′na⌋=⌊d′a′⌋=⌊d′⌊na⌋⌋?
-
∀ a , b , c ∈ Z , ⌊ a b c ⌋ = ⌊ ⌊ a b ⌋ c ⌋ \forall a,b,c\in \mathbb{Z}, \lfloor\frac{a}{bc}\rfloor = \lfloor \frac{\lfloor\frac{a}{b}\rfloor}{c} \rfloor ∀a,b,c∈Z,⌊bca⌋=⌊c⌊ba⌋⌋
证明: a b = ⌊ a b ⌋ + r \frac{a}{b}=\lfloor\frac{a}{b}\rfloor+r ba=⌊ba⌋+r, r ∈ [ 0 , 1 ) r\in [0, 1) r∈[0,1)
⌊ a b c ⌋ = ⌊ a b × 1 c ⌋ = ⌊ 1 c ( ⌊ a b ⌋ + r ) ⌋ = ⌊ ⌊ a b ⌋ c + r c ⌋ = ⌊ ⌊ a b ⌋ c ⌋ \lfloor\frac{a}{bc}\rfloor = \lfloor\frac{a}{b}\times \frac{1}{c}\rfloor=\lfloor\frac{1}{c}(\lfloor\frac{a}{b}\rfloor+r)\rfloor=\lfloor\frac{\lfloor\frac{a}{b}\rfloor}{c} + \frac{r}{c}\rfloor=\lfloor\frac{\lfloor\frac{a}{b}\rfloor}{c}\rfloor ⌊bca⌋=⌊ba×c1⌋=⌊c1(⌊ba⌋+r)⌋=⌊c⌊ba⌋+cr⌋=⌊c⌊ba⌋⌋
最后,通过整除分块计算最终的式子即可, μ \mu μ 函数预处理前缀和。查询的答案就是 f ( k ) f(k) f(k)
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 5e4 + 10;
int mu[N], vis[N], prime[N], cnt;
void prework() { //筛法求莫比乌斯函数
mu[1] = 1;
for (int i = 2; i < N; i ++) {
if (!vis[i]) prime[ ++ cnt] = i, mu[i] = -1;
for (int j = 1; prime[j] * i < N; j ++) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) break;
mu[prime[j] * i] = -mu[i];
}
}
for (int i = 1; i < N; i ++) //前缀和
mu[i] += mu[i - 1];
}
int f(int a, int b, int k) {
a = a / k, b = b / k;
int res = 0;
for (int l = 1, r; l <= min(a, b); l = r + 1) { //整除分块
r = min(a / (a / l), b / (b / l));
res += (mu[r] - mu[l - 1]) * (a / l) * (b / l);
}
return res;
}
void solve() {
int a, b, c, d, k;
cin >> a >> b >> c >> d >> k;
cout << f(b, d, k) - f(a - 1, d, k) - f(b, c - 1, k) + f(a - 1, c - 1, k) << endl; //差分
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
prework();
int dt;
cin >> dt;
while (dt --)
solve();
return 0;
}
设
d
(
x
)
d(x)
d(x) 为
x
x
x 的约数个数,给定
n
,
m
n,m
n,m,求
∑
i
=
1
n
∑
j
=
1
m
d
(
i
j
)
\sum_{i=1}^n\sum_{j=1}^md(ij)
i=1∑nj=1∑md(ij)
1 ≤ T , n , m ≤ 50000 1\le T,n,m \le 50000 1≤T,n,m≤50000
d ( i j ) = ∑ x ∣ i ∑ y ∣ i [ gcd ( x , y ) = 1 ] \mathrm{d}(ij)=\sum_{x|i}\sum_{y|i}[\gcd(x,y)=1] d(ij)=x∣i∑y∣i∑[gcd(x,y)=1]
注: d ( i ) \mathrm{d}(i) d(i) 表示 i i i 的约数个数
记 r e s \mathrm{res} res 为答案,则 r e s = ∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j [ gcd ( x , y ) = 1 ] \mathrm{res}=\sum_{i=1}^n\sum_{j=1}^m\sum_{x|i}\sum_{y|j}[\gcd(x,y)=1] res=∑i=1n∑j=1m∑x∣i∑y∣j[gcd(x,y)=1]
观察发现后半部分与上题惊人的类似,所以不难想到可以设:
F
(
n
)
=
∑
i
=
1
N
∑
j
=
1
M
∑
x
∣
i
∑
y
∣
j
[
n
∣
gcd
(
x
,
y
)
]
f
(
n
)
=
∑
i
=
1
N
∑
j
=
1
M
∑
x
∣
i
∑
y
∣
j
[
gcd
(
x
,
y
)
=
n
]
\begin{aligned} &F(n)=\sum_{i=1}^N\sum_{j=1}^M\sum_{x|i}\sum_{y|j}[n|\gcd(x,y)]\\ &f(n)=\sum_{i=1}^N\sum_{j=1}^M\sum_{x|i}\sum_{y|j}[\gcd(x,y)=n] \end{aligned}
F(n)=i=1∑Nj=1∑Mx∣i∑y∣j∑[n∣gcd(x,y)]f(n)=i=1∑Nj=1∑Mx∣i∑y∣j∑[gcd(x,y)=n]
则有:
F
(
n
)
=
∑
n
∣
d
f
(
d
)
F(n)=\sum_{n|d}f(d)
F(n)=∑n∣df(d)
故: f ( n ) = ∑ n ∣ d μ ( n d ) F ( d ) f(n)=\sum_{n|d}\mu(\frac{n}{d})F(d) f(n)=∑n∣dμ(dn)F(d)
继续化简:
f
(
n
)
=
∑
n
∣
d
μ
(
n
d
)
F
(
d
)
=
∑
n
∣
d
μ
(
n
d
)
∑
i
=
1
N
∑
j
=
1
M
∑
x
∣
i
∑
y
∣
j
[
n
∣
gcd
(
x
,
y
)
]
=
∑
n
∣
d
μ
(
n
d
)
∑
i
=
1
N
∑
j
=
1
M
∑
x
∣
i
∑
y
∣
j
[
n
∣
x
,
n
∣
y
]
=
∑
n
∣
d
μ
(
n
d
)
∑
x
=
1
N
∑
y
=
1
M
∑
x
∣
i
∑
y
∣
j
[
n
∣
x
,
n
∣
y
]
=
∑
n
∣
d
μ
(
n
d
)
∑
x
=
1
N
∑
y
=
1
M
⌊
N
x
⌋
⌊
M
y
⌋
[
n
∣
x
,
n
∣
y
]
→
观察到
x
,
y
必须都是
n
的倍数,所以引出下面的
x
′
,
y
′
=
∑
n
∣
d
μ
(
n
d
)
∑
x
′
=
1
N
n
∑
y
′
=
1
M
n
⌊
N
x
′
n
⌋
⌊
M
y
′
n
⌋
→
x
′
=
⌊
x
n
⌋
,
y
′
=
⌊
y
n
⌋
=
∑
n
∣
d
μ
(
n
d
)
∑
x
′
=
1
N
′
∑
y
′
=
1
M
′
⌊
N
′
x
′
⌋
⌊
M
′
y
′
⌋
→
N
′
=
⌊
N
n
⌋
,
M
′
=
⌊
M
n
⌋
\begin{aligned} f(n)=&\sum_{n|d}\mu(\frac{n}{d})F(d)\\ =&\sum_{n|d}\mu(\frac{n}{d})\sum_{i=1}^N\sum_{j=1}^M\sum_{x|i}\sum_{y|j}[n|\gcd(x,y)]\\ =&\sum_{n|d}\mu(\frac{n}{d})\sum_{i=1}^N\sum_{j=1}^M\sum_{x|i}\sum_{y|j}[n|x,n|y]\\ =&\sum_{n|d}\mu(\frac{n}{d})\sum_{x=1}^N\sum_{y=1}^M\sum_{x|i}\sum_{y|j}[n|x,n|y]\\ =&\sum_{n|d}\mu(\frac{n}{d})\sum_{x=1}^N\sum_{y=1}^M\lfloor\frac{N}{x}\rfloor\lfloor\frac{M}{y}\rfloor[n|x,n|y]\rightarrow 观察到\ x,y\ 必须都是\ n\ 的倍数,所以引出下面的\ x',y'\\ =&\sum_{n|d}\mu(\frac{n}{d})\sum_{x'=1}^{\frac{N}{n}}\sum_{y'=1}^{\frac{M}{n}}\lfloor\frac{N}{x'n}\rfloor\lfloor\frac{M}{y'n}\rfloor\rightarrow x'=\lfloor\frac{x}{n}\rfloor,y'=\lfloor\frac{y}{n}\rfloor\\ =&\sum_{n|d}\mu(\frac{n}{d})\sum_{x'=1}^{N'}\sum_{y'=1}^{M'}\lfloor\frac{N'}{x'}\rfloor\lfloor\frac{M'}{y'}\rfloor\rightarrow N'=\lfloor\frac{N}{n}\rfloor,M'=\lfloor\frac{M}{n}\rfloor\\ \end{aligned}
f(n)=======n∣d∑μ(dn)F(d)n∣d∑μ(dn)i=1∑Nj=1∑Mx∣i∑y∣j∑[n∣gcd(x,y)]n∣d∑μ(dn)i=1∑Nj=1∑Mx∣i∑y∣j∑[n∣x,n∣y]n∣d∑μ(dn)x=1∑Ny=1∑Mx∣i∑y∣j∑[n∣x,n∣y]n∣d∑μ(dn)x=1∑Ny=1∑M⌊xN⌋⌊yM⌋[n∣x,n∣y]→观察到 x,y 必须都是 n 的倍数,所以引出下面的 x′,y′n∣d∑μ(dn)x′=1∑nNy′=1∑nM⌊x′nN⌋⌊y′nM⌋→x′=⌊nx⌋,y′=⌊ny⌋n∣d∑μ(dn)x′=1∑N′y′=1∑M′⌊x′N′⌋⌊y′M′⌋→N′=⌊nN⌋,M′=⌊nM⌋
经过一番推导,可以发现后面的式子可以用整除分块做了,即:
∑
x
′
=
1
N
′
∑
y
′
=
1
M
′
⌊
N
′
x
′
⌋
⌊
M
′
y
′
⌋
=
∑
x
′
=
1
N
′
⌊
N
′
x
′
⌋
∑
y
′
=
1
M
′
⌊
M
′
y
′
⌋
\begin{aligned} &\sum_{x'=1}^{N'}\sum_{y'=1}^{M'}\lfloor\frac{N'}{x'}\rfloor\lfloor\frac{M'}{y'}\rfloor\\ =&\sum_{x'=1}^{N'}\lfloor\frac{N'}{x'}\rfloor\sum_{y'=1}^{M'}\lfloor\frac{M'}{y'}\rfloor \end{aligned}
=x′=1∑N′y′=1∑M′⌊x′N′⌋⌊y′M′⌋x′=1∑N′⌊x′N′⌋y′=1∑M′⌊y′M′⌋
那么,令
g
(
n
)
=
∑
i
=
1
n
⌊
n
i
⌋
g(n)=\sum_{i=1}^{n}\lfloor\frac{n}{i}\rfloor
g(n)=∑i=1n⌊in⌋,则
∑
x
′
=
1
N
′
⌊
N
′
x
′
⌋
∑
y
′
=
1
M
′
⌊
M
′
y
′
⌋
=
g
(
N
′
)
g
(
M
′
)
\sum_{x'=1}^{N'}\lfloor\frac{N'}{x'}\rfloor\sum_{y'=1}^{M'}\lfloor\frac{M'}{y'}\rfloor=g(N')g(M')
∑x′=1N′⌊x′N′⌋∑y′=1M′⌊y′M′⌋=g(N′)g(M′)
代入会原式得:
f
(
n
)
=
∑
n
∣
d
μ
(
n
d
)
F
(
d
)
=
∑
n
∣
d
μ
(
n
d
)
g
(
⌊
N
d
⌋
)
g
(
⌊
M
d
⌋
)
=
∑
d
′
=
1
μ
(
d
′
)
g
(
⌊
N
n
d
′
⌋
)
g
(
⌊
M
n
d
′
⌋
)
→
d
′
=
d
n
=
∑
d
′
=
1
μ
(
d
′
)
g
(
⌊
N
′
d
′
⌋
)
g
(
⌊
M
′
d
′
⌋
)
→
N
′
=
⌊
N
n
⌋
,
M
′
=
⌊
M
n
⌋
\begin{aligned} f(n)=&\sum_{n|d}\mu(\frac{n}{d})F(d)\\ =&\sum_{n|d}\mu(\frac{n}{d})g(\lfloor\frac{N}{d}\rfloor)g(\lfloor\frac{M}{d}\rfloor)\\ =&\sum_{d'=1}\mu(d')g(\lfloor\frac{N}{nd'}\rfloor)g(\lfloor\frac{M}{nd'}\rfloor)\rightarrow d'=\frac{d}{n}\\ =&\sum_{d'=1}\mu(d')g(\lfloor\frac{N'}{d'}\rfloor)g(\lfloor\frac{M'}{d'}\rfloor)\rightarrow N'=\lfloor\frac{N}{n}\rfloor,M'=\lfloor\frac{M}{n}\rfloor\\ \end{aligned}
f(n)====n∣d∑μ(dn)F(d)n∣d∑μ(dn)g(⌊dN⌋)g(⌊dM⌋)d′=1∑μ(d′)g(⌊nd′N⌋)g(⌊nd′M⌋)→d′=ndd′=1∑μ(d′)g(⌊d′N′⌋)g(⌊d′M′⌋)→N′=⌊nN⌋,M′=⌊nM⌋
这时候,发现可以在此进行整除分块,这样求一个
f
(
n
)
f(n)
f(n) 的时间复杂度为
n
\sqrt{n}
n,则有
q
q
q 次查询,总时间复杂度为
O
(
q
n
)
O(q\sqrt n)
O(qn)
最终的答案为:
f
(
1
)
=
∑
d
=
1
μ
(
d
′
)
g
(
⌊
N
d
⌋
)
g
(
⌊
M
d
⌋
)
f(1)=\sum_{d=1}\mu(d')g(\lfloor\frac{N}{d}\rfloor)g(\lfloor\frac{M}{d}\rfloor)
f(1)=d=1∑μ(d′)g(⌊dN⌋)g(⌊dM⌋)
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 5e4 + 10;
int n, m;
int mu[N], prime[N], cnt, vis[N];
int g[N];
void prework() {
mu[1] = 1;
for (int i = 2; i < N; i ++) {
if (!vis[i]) prime[ ++ cnt] = i, mu[i] = -1;
for (int j = 1; prime[j] * i < N; j ++) {
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
mu[i * prime[j]] = -mu[i];
}
}
for (int i = 1; i < N; i ++)
mu[i] += mu[i - 1];
for (int i = 1; i < N; i ++) {
for (int l = 1, r; l <= i; l = r + 1) {
r = min(i, i / (i / l));
g[i] += (r - l + 1) * (i / l);
}
}
}
void solve() {
cin >> n >> m;
LL res = 0;
for (int l = 1, r; l <= min(n, m); l = r + 1) {
r = min(min(n / (n / l), m / (m / l)), min(n, m));
res += (LL)(mu[r] - mu[l - 1]) * g[n / l] * g[m / l];
}
cout << res << '\n';
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
prework();
int dt;
cin >> dt;
while (dt --)
solve();
return 0;
}