P2522 [HAOI2011]Problem b (莫比乌斯反演)
作者:互联网
题目大意:
题目链接
n
n
n个询问,给定
a
,
b
,
c
,
d
,
k
a,b,c,d,k
a,b,c,d,k,询问
∑
x
=
a
b
∑
x
=
c
d
[
g
c
d
(
x
,
y
)
=
=
k
]
\sum_{x=a}^{b}\sum_{x=c}^{d}[gcd(x,y)==k]
∑x=ab∑x=cd[gcd(x,y)==k]
解题思路:
∑ x = a b ∑ x = c d [ g c d ( x , y ) = = k ] = ∑ x = 1 b ∑ x = 1 d [ g c d ( x , y ) = = k ] − ∑ x = 1 a − 1 ∑ x = 1 d [ g c d ( x , y ) = = k ] − ∑ x = 1 b ∑ x = 1 d − 1 [ g c d ( x , y ) = = k ] + ∑ x = 1 a − 1 ∑ x = 1 c − 1 [ g c d ( x , y ) = = k ] \sum_{x=a}^{b}\sum_{x=c}^{d}[gcd(x,y)==k]=\sum_{x=1}^{b}\sum_{x=1}^{d}[gcd(x,y)==k]-\sum_{x=1}^{a-1}\sum_{x=1}^{d}[gcd(x,y)==k]-\sum_{x=1}^{b}\sum_{x=1}^{d-1}[gcd(x,y)==k]+\sum_{x=1}^{a-1}\sum_{x=1}^{c-1}[gcd(x,y)==k] ∑x=ab∑x=cd[gcd(x,y)==k]=∑x=1b∑x=1d[gcd(x,y)==k]−∑x=1a−1∑x=1d[gcd(x,y)==k]−∑x=1b∑x=1d−1[gcd(x,y)==k]+∑x=1a−1∑x=1c−1[gcd(x,y)==k]
发现四个算式本质形式是一样的
所以我们只需要知道 ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = = k ] \sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)==k] ∑i=1n∑j=1m[gcd(i,j)==k]如何计算
∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = = k ] = ∑ i = 1 n k ∑ j = 1 m k [ g c d ( i , j ) = = 1 ] \sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)==k]=\sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}k}[gcd(i,j)==1] ∑i=1n∑j=1m[gcd(i,j)==k]=∑i=1kn∑j=1km[gcd(i,j)==1]
∑ i = 1 n k ∑ j = 1 m k [ g c d ( i , j ) = = 1 ] = ∑ i = 1 n k ∑ j = 1 m k ε ( g c d ( i , j ) ) \sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}k}[gcd(i,j)==1]=\sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}k}\varepsilon (gcd(i,j)) ∑i=1kn∑j=1km[gcd(i,j)==1]=∑i=1kn∑j=1kmε(gcd(i,j))
∑ i = 1 n k ∑ j = 1 m k ε ( g c d ( i , j ) ) = ∑ i = 1 n k ∑ j = 1 m k ∑ d ∣ g c d ( i , j ) μ ( d ) \sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}k}\varepsilon (gcd(i,j))=\sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}k}\sum_{d|gcd(i,j)} \mu(d) ∑i=1kn∑j=1kmε(gcd(i,j))=∑i=1kn∑j=1km∑d∣gcd(i,j)μ(d)
变化求和顺序,枚举公约数
∑ i = 1 n k ∑ j = 1 m k ∑ d ∣ g c d ( i , j ) μ ( d ) = ∑ d = 1 μ ( d ) ∑ i = 1 n k [ d ∣ i ] ∑ j = 1 m k [ d ∣ j ] \sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}k}\sum_{d|gcd(i,j)} \mu(d)=\sum_{d=1}\mu(d)\sum_{i=1}^{\frac nk}[d|i]\sum_{j=1}^{\frac mk}[d|j] ∑i=1kn∑j=1km∑d∣gcd(i,j)μ(d)=∑d=1μ(d)∑i=1kn[d∣i]∑j=1km[d∣j]
因为 [ 1 , n k ] [1,\frac nk] [1,kn]中d的倍数有 n k d \frac{n}{kd} kdn个
∑ d = 1 μ ( d ) ∑ i = 1 n k [ d ∣ i ] ∑ j = 1 m k [ d ∣ j ] = ∑ d = 1 μ ( d ) ⌊ n k d ⌋ ⌊ m k d ⌋ \sum_{d=1}\mu(d)\sum_{i=1}^{\frac nk}[d|i]\sum_{j=1}^{\frac mk}[d|j]=\sum_{d=1}\mu(d)\left \lfloor \frac n{kd} \right \rfloor\left \lfloor \frac m{kd} \right \rfloor ∑d=1μ(d)∑i=1kn[d∣i]∑j=1km[d∣j]=∑d=1μ(d)⌊kdn⌋⌊kdm⌋
惊讶的发现这不就是数论分块的基本形式,接下来先算出 μ ( ) \mu() μ(),然后分块做即可
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int T, a, b, c, d, k, cnt;
int mu[maxn], p[maxn], vis[maxn];
void init() {
mu[1] = vis[1] = 1;
for (int i = 2; i < maxn; i++) {
if (!vis[i]) p[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * p[j] < maxn; j++) {
vis[i * p[j]] = 1;
if (i % p[j] == 0) {
mu[i * p[j]] = 0;
break;
}
else
mu[i * p[j]] = -mu[i];
}
}
for (int i = 1; i < maxn; i++) mu[i] += mu[i - 1];//求前缀和
}
int solve(int n, int m) {
int res = 0;
for (int i = 1, j; i <= std::min(n, m); i = j + 1) {
j = min(n / (n / i), m / (m / i));//取min即可
res += (mu[j] - mu[i - 1]) * (n / i) * (m / i);
//数论分块标准的计算形式 i到j的和*(n/i)
}
return res;
}
int main() {
init();
cin >> T;
while (T--) {
cin >> a >> b >> c >> d >> k;
cout << solve(b / k, d / k) - solve(b / k, (c - 1) / k) - solve((a - 1) / k, d / k)
+ solve((a - 1) / k, (c - 1) / k) << endl;
}
}
标签:frac,gcd,int,sum,mu,反演,HAOI2011,P2522,1kn 来源: https://blog.csdn.net/weixin_45691711/article/details/110309792