题目大意:让你求 ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] , p ∈ p r i m e \sum_{i = 1}^n\sum_{j = 1}^m[gcd(i,j) = p],p \in prime ∑i=1n∑j=1m[gcd(i,j)=p],p∈prime
转化一下式子,枚举 p:
∑
p
=
2
n
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
p
]
,
p
∈
p
r
i
m
e
\sum_{p = 2}^n\sum_{i = 1}^n\sum_{j = 1}^m[gcd(i,j) = p],p\in prime
p=2∑ni=1∑nj=1∑m[gcd(i,j)=p],p∈prime
这个式子等价于:
∑
p
=
2
n
∑
i
=
1
⌊
n
p
⌋
∑
j
=
1
⌊
m
p
⌋
[
g
c
d
(
i
,
j
)
=
1
]
,
p
∈
p
r
i
m
e
\sum_{p = 2}^n\sum_{i = 1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p}\rfloor}[gcd(i,j) = 1],p\in prime
p=2∑ni=1∑⌊pn⌋j=1∑⌊pm⌋[gcd(i,j)=1],p∈prime
根据莫比乌斯函数性质,
[
g
c
d
(
i
,
j
)
=
1
]
[gcd(i,j) = 1]
[gcd(i,j)=1]可以替换成:
∑
d
∣
g
c
d
(
i
,
j
)
μ
(
d
)
\sum_{d | gcd(i,j)}\mu(d)
∑d∣gcd(i,j)μ(d),整个式子变成:
∑
p
=
2
n
∑
i
=
1
⌊
n
p
⌋
∑
j
=
1
⌊
m
p
⌋
∑
d
∣
g
c
d
(
i
,
j
)
μ
(
d
)
,
p
∈
p
r
i
m
e
\sum_{p = 2}^n\sum_{i = 1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p}\rfloor}\sum_{d | gcd(i,j)}\mu(d),p\in prime
p=2∑ni=1∑⌊pn⌋j=1∑⌊pm⌋d∣gcd(i,j)∑μ(d),p∈prime
∑
i
=
1
⌊
n
p
⌋
∑
j
=
1
⌊
m
p
⌋
∑
d
∣
g
c
d
(
i
,
j
)
μ
(
d
)
\sum_{i = 1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p}\rfloor}\sum_{d | gcd(i,j)}\mu(d)
∑i=1⌊pn⌋∑j=1⌊pm⌋∑d∣gcd(i,j)μ(d) 这里改变一下枚举项,枚举 d:
∑
p
=
2
n
∑
d
=
1
⌊
n
p
⌋
μ
(
d
)
∑
i
=
1
⌊
n
p
∗
d
⌋
∑
j
=
1
⌊
m
p
∗
d
⌋
,
p
∈
p
r
i
m
e
\sum_{p = 2}^n\sum_{d = 1}^{\lfloor\frac{n}{p}\rfloor}\mu(d)\sum_{i = 1}^{\lfloor\frac{n}{p*d}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{p*d}\rfloor},p\in prime
p=2∑nd=1∑⌊pn⌋μ(d)i=1∑⌊p∗dn⌋j=1∑⌊p∗dm⌋,p∈prime
这时右半边直接等于:
⌊
n
p
∗
d
⌋
∗
⌊
m
p
∗
d
⌋
\lfloor\frac{n}{p * d}\rfloor*\lfloor\frac{m}{p * d}\rfloor
⌊p∗dn⌋∗⌊p∗dm⌋,化简到这一步可以两层数论分块,单组O(n)解决,但题目有T组,复杂度还需要优化。
令
T
=
p
∗
d
T = p * d
T=p∗d:
∑
p
=
2
n
∑
d
=
1
⌊
n
p
⌋
μ
(
d
)
∗
⌊
n
T
⌋
∗
⌊
m
T
⌋
,
p
∈
p
r
i
m
e
\sum_{p = 2}^n\sum_{d = 1}^{\lfloor\frac{n}{p}\rfloor}\mu(d)*\lfloor\frac{n}{T}\rfloor*\lfloor\frac{m}{T}\rfloor ,p\in prime
p=2∑nd=1∑⌊pn⌋μ(d)∗⌊Tn⌋∗⌊Tm⌋,p∈prime
再改变枚举项,枚举T:
∑
T
=
1
n
⌊
n
T
⌋
∗
⌊
m
T
⌋
∗
∑
p
∣
T
μ
(
T
p
)
,
p
∈
p
r
i
m
e
\sum_{T = 1}^n\lfloor\frac{n}{T}\rfloor*\lfloor\frac{m}{T}\rfloor*\sum_{p | T}\mu(\frac{T}{p}),p\in prime
T=1∑n⌊Tn⌋∗⌊Tm⌋∗p∣T∑μ(pT),p∈prime
注意此时莫比乌斯函数部分可以预处理,令
F
(
T
)
=
∑
p
∣
T
μ
(
T
p
)
F(T) = \sum_{p | T}\mu(\frac{T}{p})
F(T)=∑p∣Tμ(pT),可以用埃筛在
n
l
o
g
l
o
g
n
nloglogn
nloglogn时间内筛出
F
F
F函数,再求一下前缀和,然后数论分块即可在单组
s
q
r
t
(
n
)
sqrt(n)
sqrt(n)时间内完成
复杂度为
O
(
T
∗
s
q
r
t
(
n
)
)
O(T * sqrt(n))
O(T∗sqrt(n)),T为询问组数
代码:
(太多的long long 运算会超时)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e7 + 10;
const int mx = 1e7;
typedef long long ll;
int t,n,m;
bool ispri[maxn];
int pri[maxn];
int mu[maxn];
int sum[maxn];
void sieve(int n) {
mu[1] = 1;
ispri[0] = ispri[1] = true;
pri[0] = 0;
for(int i = 2; i <= n; i++) {
if(!ispri[i]) {
pri[++pri[0]] = i;
mu[i] = -1;
}
for(int j = 1; j <= pri[0] && i * pri[j] <= n; j++) {
ispri[i * pri[j]] = true;
if(i % pri[j] == 0) break;
mu[i * pri[j]] = -mu[i];
}
}
for(int i = 1; i <= pri[0]; i++)
for(int j = 1; j * pri[i] <= n; j++)
sum[j * pri[i]] += mu[j];
for(int i = 1; i <= n; i++)
sum[i] += sum[i - 1];
}
int main() {
scanf("%d",&t);
sieve(10000000);
while(t--) {
scanf("%d%d",&n,&m);
if(n > m) swap(n,m);
int i,j;
ll res = 0;
for(i = 1; i <= n; i = j + 1) {
j = min(n / (n / i),m / (m / i));
int p1 = n / i,p2 = m / i;
res += 1ll * p1 * p2 * (sum[j] - sum[i - 1]);
}
printf("%lld\n",res);
}
return 0;
}