P r o b l e m b Problem\ b Problem b
D
e
s
c
r
i
p
t
i
o
n
\mathcal{Description}
Description
对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。
最
初
想
法
最初想法
最初想法
A
n
s
=
∑
i
=
1
⌊
b
k
⌋
∑
j
=
1
⌊
d
k
⌋
[
g
c
d
(
i
,
j
)
=
k
]
−
∑
i
=
1
⌊
a
−
1
k
⌋
∑
j
=
1
⌊
d
k
⌋
[
g
c
d
(
i
,
j
)
=
k
]
−
∑
i
=
1
⌊
b
k
⌋
∑
j
=
1
⌊
c
−
1
k
⌋
[
g
c
d
(
i
,
j
)
=
k
]
+
∑
i
=
1
⌊
a
−
1
k
⌋
∑
j
=
1
⌊
c
−
1
k
⌋
[
g
c
d
(
i
,
j
)
=
k
]
Ans=\sum_{i=1}^{\lfloor \frac{b}{k} \rfloor}\sum_{j=1}^{\lfloor \frac{d}{k} \rfloor}[gcd(i,j)=k]- \sum_{i=1}^{\lfloor \frac{a-1}{k} \rfloor}\sum_{j=1}^{\lfloor \frac{d}{k} \rfloor} [ gcd(i,j)=k ] - \sum_{i=1}^{\lfloor \frac{b}{k} \rfloor}\sum_{j=1}^{\lfloor \frac{c-1}{k} \rfloor} [ gcd(i,j)=k ] + \sum_{i=1}^{\lfloor \frac{a-1}{k} \rfloor}\sum_{j=1}^{\lfloor \frac{c-1}{k} \rfloor} [ gcd(i,j)=k ]
Ans=i=1∑⌊kb⌋j=1∑⌊kd⌋[gcd(i,j)=k]−i=1∑⌊ka−1⌋j=1∑⌊kd⌋[gcd(i,j)=k]−i=1∑⌊kb⌋j=1∑⌊kc−1⌋[gcd(i,j)=k]+i=1∑⌊ka−1⌋j=1∑⌊kc−1⌋[gcd(i,j)=k]
但是要使用 莫比乌斯反演, 于是回去学习…
正
解
部
分
正解部分
正解部分
N
N
N 年过后… 莫比乌斯反演学会了.
click here
这里不再赘述 .
实 现 部 分 实现部分 实现部分
#include<cstdio>
#include<algorithm>
#define reg register
const int maxn = 50005;
int prime_num;
int mu[maxn];
int mu_sum[maxn];
int prime[maxn];
bool is_prime[maxn];
void sieve(){
prime_num = 0, mu[1] = 1;
for(reg int i = 2; i < maxn; i ++){
if(!is_prime[i]) prime[++ prime_num] = i, mu[i] = -1;
for(reg int j = 1; j <= prime_num && i*prime[j] < maxn; j ++){
int t = i*prime[j];
is_prime[t] = 1;
if(i%prime[j] == 0){ mu[t] = 0; break ; }
mu[t] = -mu[i];
}
}
for(reg int i = 1; i < maxn; i ++) mu_sum[i] = mu_sum[i-1] + mu[i];
}
int Calc(int n, int m){
int lim = std::min(n, m), s = 0;
for(reg int l = 1, r; l <= lim; l = r+1){
r = std::min(n/(n/l), m/(m/l));
s += (mu_sum[r] - mu_sum[l-1]) * (n/l) * (m/l);
}
return s;
}
void Work(){
int a, b, c, d, k;
scanf("%d%d%d%d%d", &a, &b, &c, &d, &k);
int Ans = Calc(b/k, d/k) - Calc((a-1)/k, d/k) - Calc(b/k, (c-1)/k) + Calc((a-1)/k, (c-1)/k);
printf("%d\n", Ans);
}
int main(){
sieve();
int T;
scanf("%d", &T);
while(T --) Work();
return 0;
}