-数论-莫比乌斯反演-容斥- [SP26017]GCDMAT - GCD OF MATRIX

题目描述

Link

Solution

其实如果这道题没有容斥的操作就是这样:

然后我们可以推一下:

设 $T=ad​$

因为 $\sum_{d | T} d \mu({\lfloor \frac{T}{d} \rfloor})​$ 这部分是狄利克雷卷积的形式,而 $id * \mu = \varphi​$

所以线性筛一遍欧拉函数再用整除分块就行了。

最后再用容斥瞎搞搞就可以了。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 500010
#define MOD 1000000007
#define ll long long
#define int long long
int p[MAXN + 10], tot, phi[MAXN + 10], T, g[MAXN + 10], answ;
bool chk[MAXN + 10];
template <typename Tp>
Tp min(Tp a, Tp b) {
if (a < b) return a;
else return b;
}
template <typename Tp>
Tp max(Tp a, Tp b) {
if (a > b) return a;
else return b;
}
void sieve() {
phi[1] = 1;
chk[1] = true;
for (int i = 2; i <= MAXN; i++) {
if (!chk[i]) {
p[++tot] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= tot && i * p[j] <= MAXN; j++) {
chk[i * p[j]] = 1;
if (!(i % p[j])) {
phi[i * p[j]] = phi[i] * p[j];
break;
}
phi[i * p[j]] = phi[i] * phi[p[j]];
}
}
for (int i = 1; i <= MAXN; i++) {
g[i] = (g[i - 1] + phi[i]) % MOD;
}
}
int sum(int x, int y) {
int n = min(x, y);
int m = max(x, y);
ll ans = 0;
for (int l = 1, r; l <= n; l = r + 1) {
r = min(n / (n / l), m / (m / l));
ans += (((n / l) % MOD * (m / l) % MOD) % MOD) * ((g[r] - g[l - 1] + MOD) % MOD) % MOD;
}
return (ans % MOD);
}
int a, b, c, d, n, m;
signed main() {
sieve();
scanf("%lld", &T);
scanf("%lld%lld", &n, &m);
while (T--) {
scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
answ = (sum(c, d) + sum(a - 1, b - 1) - sum(c, b - 1) - sum(d, a - 1) + 2 * MOD) % MOD;
printf("%lld\n", answ % MOD);
}
}
文章作者: RiverFun
文章链接: https://stevebraveman.github.io/blog/2019/04/18/75/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 RiverFun

评论