YY的GCD
洛谷有, 卡快读
题面
神犇 YY 虐完数论后给傻× kAc 出了一题
给定 N, M 且 gcd(x,y) 为质数的 (x, y)(x,y) 有多少对。
输入格式
第一行一个整数 T 表述数据组数。
接下来 T 行,每行两个正整数,N, M。
输出格式
T 行,每行一个整数表示第 i 组数据的结果。
输入输出样例
输入1
2
10 10
100 100
输出1
30
2791
$ T = 10^4,N, M \leq 10^7$
题解
设 F(n) 表示 gcd(x, y) == k的倍数 的(x, y)的对数, f(n) 表示 gcd(x, y) == k 的(x, y)的对数
$F(n) = \sum_{n | d} f(d) = \left \lfloor \frac {n} {k} \right \rfloor \times \left \lfloor \frac {m} {k} \right \rfloor $
由莫比乌斯反演得, \(f(n) = \sum_{n | d} \mu (\frac {d} {n}) F(d)\)
变换区间, 左区间向上、右区间向下取整, 直接求 gcd(x / k, y / k) == 1, 即f(1) 为解
\(f(1) = \sum_{d = 1}^{\left \lfloor \frac {min(n, m)} {k} \right \rfloor} \mu (d) \times \left \lfloor \frac {n} {k} \right \rfloor \times \left \lfloor \frac {m} {k} \right \rfloor\)
\(ans = \sum_{p \in prime} \sum_{p | d} \mu (\frac {d} {p}) \times F(d)\)
设 d = k * p
\(ans = \sum_{p \in prime} \sum_{k = 1}^{\frac {min(n, m)} {p} } \mu (k) \times F(kp)\)
即
\(ans = \sum_{d = 1}^{min(n, m)} F(d) \times \sum_{p \in d_{prime}} \mu (d)\)
带入 F(n) 分块可求, \(\sum_{p \in d_{prime}} \mu (d)\) 预处理前缀和
//快读省略
const int N = 1e7 + 5;
int n, m = 1e7, _, k;
int prime[N], miu[N], cnt, a, b;
long long sum[N], x;
bool v[N];
void init() {
miu[1] = 1;
for (int i = 2; i <= m; ++i) {
if (!v[i]) prime[++cnt] = i, miu[i] = -1;
for (int j = 1; j <= cnt && prime[j] <= m / i; ++j) {
v[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
miu[prime[j] * i] = -miu[i];
}
}
for (int i = 1; i <= cnt; ++i)
for (int j = 1; j <= m / prime[i]; ++j) sum[prime[i] * j] += miu[j];
for (int i = 2; i <= m; ++i) sum[i] += sum[i - 1];
}
int main() {
init();
for (scan(_); _; --_) {
scan(a); scan(b); x = 0;
if (a > b) swap(a, b);
for (int l = 1, r; l <= a; l = r + 1) {
r = min(b / (b / l), a / (a / l));
x += (sum[r] - sum[l - 1]) * (b / l) * (a / l);
}
print(x); putchar('\n');
}
return 0;
}
即 ans = \sum_{}

浙公网安备 33010602011771号