题
意
\large题意
题意
题目链接
给
定
N
,
M
,
求
1
≤
x
≤
N
,
1
≤
y
≤
M
且
g
c
d
(
x
,
y
)
为
质
数
的
(
x
,
y
)
有
多
少
对
给定N, M,求1 \leq x \leq N, 1 \leq y \leq M且 gcd(x, y)为质数的(x, y)有多少对
给定N,M,求1≤x≤N,1≤y≤M且gcd(x,y)为质数的(x,y)有多少对
用
式
子
表
达
出
来
为
用式子表达出来为
用式子表达出来为
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
k
]
,
k
∈
P
r
i
m
e
\sum_{i=1}^{n} \sum_{j=1}^{m} [gcd(i, j) = k], k \in Prime
i=1∑nj=1∑m[gcd(i,j)=k],k∈Prime
题 解 \large题解 题解
为
了
讨
论
方
便
,
我
们
假
设
n
<
m
为了讨论方便,我们假设n < m
为了讨论方便,我们假设n<m
原
式
=
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
k
]
,
k
∈
p
r
i
m
e
=
∑
k
=
1
n
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
k
]
,
k
∈
p
r
i
m
e
,
后
面
省
略
这
句
话
=
∑
k
=
1
n
∑
i
=
1
n
/
k
∑
j
=
1
m
/
k
[
g
c
d
(
i
,
j
)
=
1
]
=
∑
k
=
1
n
∑
i
=
1
n
/
k
∑
j
=
1
m
/
k
∑
d
∣
g
c
d
(
i
,
j
)
n
/
k
μ
(
d
)
=
∑
k
=
1
n
∑
d
=
1
n
/
k
μ
(
d
)
⌊
n
k
d
⌋
⌊
m
k
d
⌋
\begin{aligned} \qquad\qquad\qquad 原式 &=\sum_{i=1}^{n} \sum_{j=1}^{m} [gcd(i, j) = k], k \in prime \\ &= \sum_{k=1}^{n} \sum_{i=1}^{n} \sum_{j=1}^{m} [gcd(i, j) = k], k \in prime, 后面省略这句话 \\ &= \sum_{k=1}^{n} \sum_{i=1}^{n/k} \sum_{j=1}^{m/k} [gcd(i, j) = 1] \\ &= \sum_{k=1}^{n} \sum_{i=1}^{n/k} \sum_{j=1}^{m/k} \sum_{d|gcd(i, j)}^{n/k} \mu(d) \\ &= \sum_{k=1}^{n} \sum_{d=1}^{n/k} \mu(d) \lfloor \frac{n}{kd}\rfloor \lfloor \frac{m}{kd}\rfloor \end{aligned}
原式=i=1∑nj=1∑m[gcd(i,j)=k],k∈prime=k=1∑ni=1∑nj=1∑m[gcd(i,j)=k],k∈prime,后面省略这句话=k=1∑ni=1∑n/kj=1∑m/k[gcd(i,j)=1]=k=1∑ni=1∑n/kj=1∑m/kd∣gcd(i,j)∑n/kμ(d)=k=1∑nd=1∑n/kμ(d)⌊kdn⌋⌊kdm⌋
在
这
里
我
们
枚
举
素
数
k
,
可
以
得
到
答
案
,
但
是
实
际
上
会
T
L
E
,
我
们
考
虑
如
何
进
一
步
优
化
在这里我们枚举素数k,可以得到答案,但是实际上会TLE,我们考虑如何进一步优化
在这里我们枚举素数k,可以得到答案,但是实际上会TLE,我们考虑如何进一步优化
我
们
设
T
=
k
d
,
则
d
=
T
k
那
么
有
我们设T=kd,则d=\frac{T}{k} 那么有
我们设T=kd,则d=kT那么有
原
式
=
∑
k
=
1
n
∑
d
=
1
n
/
k
μ
(
d
)
⌊
n
k
d
⌋
⌊
m
k
d
⌋
=
∑
k
=
1
n
∑
d
=
1
n
/
k
μ
(
d
)
⌊
n
T
⌋
⌊
m
T
⌋
\begin{aligned} \qquad\qquad\qquad 原式 &=\sum_{k=1}^{n} \sum_{d=1}^{n/k} \mu(d) \lfloor \frac{n}{kd}\rfloor \lfloor \frac{m}{kd}\rfloor \\ &= \sum_{k=1}^{n} \sum_{d=1}^{n/k} \mu(d) \lfloor \frac{n}{T}\rfloor \lfloor \frac{m}{T}\rfloor \\ \end{aligned}
原式=k=1∑nd=1∑n/kμ(d)⌊kdn⌋⌊kdm⌋=k=1∑nd=1∑n/kμ(d)⌊Tn⌋⌊Tm⌋
这
个
式
子
,
现
在
是
先
枚
举
素
数
k
,
然
后
枚
举
d
,
我
们
考
虑
直
接
枚
举
T
这个式子,现在是先枚举素数k,然后枚举d,我们考虑直接枚举T
这个式子,现在是先枚举素数k,然后枚举d,我们考虑直接枚举T
原
式
=
∑
k
=
1
n
∑
d
=
1
n
/
k
μ
(
d
)
⌊
n
T
⌋
⌊
m
T
⌋
=
∑
T
=
1
n
⌊
n
T
⌋
⌊
m
T
⌋
∑
k
∈
p
r
i
m
e
,
k
∣
T
μ
(
T
k
)
=
∑
T
=
1
n
⌊
n
T
⌋
⌊
m
T
⌋
∑
k
∈
p
r
i
m
e
,
k
∣
T
μ
(
T
k
)
\begin{aligned} \qquad\qquad\qquad 原式 &=\sum_{k=1}^{n} \sum_{d=1}^{n/k} \mu(d) \lfloor \frac{n}{T}\rfloor \lfloor \frac{m}{T}\rfloor \\ &= \sum_{T=1}^{n} \lfloor \frac{n}{T}\rfloor \lfloor \frac{m}{T}\rfloor \sum_{k \in prime, k|T} \mu (\frac{T}{k}) \\ &= \sum_{T=1}^{n} \lfloor \frac{n}{T}\rfloor \lfloor \frac{m}{T}\rfloor \boxed{\sum_{k \in prime, k|T} \mu (\frac{T}{k})} \\ \end{aligned}
原式=k=1∑nd=1∑n/kμ(d)⌊Tn⌋⌊Tm⌋=T=1∑n⌊Tn⌋⌊Tm⌋k∈prime,k∣T∑μ(kT)=T=1∑n⌊Tn⌋⌊Tm⌋k∈prime,k∣T∑μ(kT)
注
意
到
,
最
后
的
东
西
,
是
可
以
预
处
理
的
注意到,最后的东西,是可以预处理的
注意到,最后的东西,是可以预处理的
考
虑
每
一
个
素
数
k
,
对
于
k
的
倍
数
T
,
把
它
的
值
加
上
μ
(
T
k
)
考虑每一个素数k,对于k的倍数T,把它的值加上\mu (\frac{T}{k})
考虑每一个素数k,对于k的倍数T,把它的值加上μ(kT)
预 处 理 代 码 如 下 \large预处理代码如下 预处理代码如下
void sieve() {
mu[1]=1;
for (int i=2;i<=10000000;i++) {
if (!flag[i]) prime[++cnt]=i,mu[i]=-1;
for (int j=1;j<=cnt&&i*prime[j]<=10000000;j++) {
flag[i*prime[j]]=1;
if (i%prime[j]==0) break;
mu[i*prime[j]]=-mu[i];
}
}
for (int i=1;i<=cnt;i++)
for (int j=1;prime[i]*j<=10000000;j++)
f[j*prime[i]]+=mu[j];
for (int i=1;i<=10000000;i++)
sum[i]=sum[i-1]+f[i];
}
我
们
推
式
子
比
较
重
要
的
一
步
是
用
了
我们推式子比较重要的一步是用了
我们推式子比较重要的一步是用了
∑
d
∣
g
c
d
(
i
,
j
)
μ
(
d
)
=
[
g
c
d
(
i
,
j
)
=
1
]
\sum_{d|gcd(i, j)} \mu(d) = [gcd(i, j) = 1]
d∣gcd(i,j)∑μ(d)=[gcd(i,j)=1]
这
个
在
许
多
题
目
中
都
会
用
到
,
是
一
个
比
较
套
路
的
用
法
这个在许多题目中都会用到,是一个比较套路的用法
这个在许多题目中都会用到,是一个比较套路的用法
同
样
的
,
我
们
可
以
使
用
莫
比
乌
斯
反
演
来
推
式
子
,
得
到
同
样
的
结
果
同样的,我们可以使用莫比乌斯反演来推式子,得到同样的结果
同样的,我们可以使用莫比乌斯反演来推式子,得到同样的结果
我
们
设
f
(
d
)
=
g
c
d
(
i
,
j
)
=
d
的
个
数
,
F
(
n
)
为
g
c
d
(
i
,
j
)
为
d
的
倍
数
的
个
数
,
我
们
有
我们设f(d) = gcd(i, j) = d的个数, F(n)为gcd(i, j)为d的倍数的个数,我们有
我们设f(d)=gcd(i,j)=d的个数,F(n)为gcd(i,j)为d的倍数的个数,我们有
f
(
d
)
=
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
d
]
f(d) = \sum_{i=1}^{n} \sum_{j=1}^{m} [gcd(i, j) = d]
f(d)=i=1∑nj=1∑m[gcd(i,j)=d]
F
(
n
)
=
∑
i
=
1
n
/
i
f
(
d
⋅
i
)
=
⌊
n
d
⌋
⌊
m
d
⌋
F(n) = \sum_{i=1}^{n/i}f(d\cdot i) = \lfloor \frac{n}{d}\rfloor \lfloor \frac{m}{d}\rfloor
F(n)=i=1∑n/if(d⋅i)=⌊dn⌋⌊dm⌋
得
到
得到
得到
f
(
d
)
=
∑
i
=
1
n
/
d
μ
(
i
)
F
(
d
⋅
i
)
f(d) =\sum_{i=1}^{n/d} \mu(i) F(d \cdot i)
f(d)=i=1∑n/dμ(i)F(d⋅i)
接
着
,
接着,
接着,
原
式
=
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
k
]
,
k
∈
p
r
i
m
e
=
∑
k
,
k
∈
p
r
i
m
e
n
f
(
k
)
=
∑
k
,
k
∈
p
r
i
m
e
n
∑
i
=
1
n
/
k
μ
(
i
)
⌊
n
d
i
⌋
⌊
m
d
i
⌋
\begin{aligned} \qquad\qquad\qquad 原式 &=\sum_{i=1}^{n} \sum_{j=1}^{m} [gcd(i, j) = k], k \in prime \\ &= \sum_{k, k \in prime}^{n} f(k) \\ &= \sum_{k, k \in prime}^{n} \sum_{i=1}^{n/k} \mu(i) \lfloor \frac{n}{di}\rfloor \lfloor \frac{m}{di}\rfloor\\ \end{aligned}
原式=i=1∑nj=1∑m[gcd(i,j)=k],k∈prime=k,k∈prime∑nf(k)=k,k∈prime∑ni=1∑n/kμ(i)⌊din⌋⌊dim⌋
i
替
换
为
字
母
k
后
,
和
上
面
是
相
同
的
结
果
i替换为字母k后,和上面是相同的结果
i替换为字母k后,和上面是相同的结果
完 整 A C 代 码 \large完整AC代码 完整AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 10000000;
LL mu[N + 10];
LL flag[N + 10];
LL prime[N + 10];
LL cnt;
LL f[N + 10];
LL sum[N + 10];
void init() {
mu[1] = 1;
for (int i = 2; i <= N; i++) {
if (!flag[i]) prime[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * prime[j] <= N; j++) {
flag[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
mu[i * prime[j]] = -mu[i];
}
}
for (int i = 1; i <= cnt; i++) {
for (int j = 1; prime[i] * j <= N; j++) {
f[j * prime[i]] += mu[j];
}
}
for (int i = 1; i <= N; i++) sum[i] = sum[i - 1] + f[i];
}
LL solve(int n, int m) {
LL ans = 0;
for (int l = 1, r; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l));
ans += (LL)(sum[r] - sum[l-1]) * (LL)(n / l) * (LL)(m / l);
}
return ans;
}
int main() {
init();
int n, m, T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
if (n > m) swap(n, m);
printf("%lld\n", solve(n, m));
}
return 0;
}