洛谷有, 卡快读
题面
神犇 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} ight floor imes left lfloor frac {m} {k} ight floor $
由莫比乌斯反演得, (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} ight floor} mu (d) imes left lfloor frac {n} {k} ight floor imes left lfloor frac {m} {k} ight floor)
(ans = sum_{p in prime} sum_{p | d} mu (frac {d} {p}) imes F(d))
设 d = k * p
(ans = sum_{p in prime} sum_{k = 1}^{frac {min(n, m)} {p} } mu (k) imes F(kp))
即
(ans = sum_{d = 1}^{min(n, m)} F(d) imes 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('
');
}
return 0;
}
即 ans = sum_{}