求 1 <= x <= n, 1 <= y <= m 中 gcd(x, y) 为质数的个数
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1e7 + 5;
int is_prime[MAXN], miu[MAXN], prime[MAXN], cnt = 0;
int pre_f[MAXN], f[MAXN];
void Primes(int N) {
miu[1] = 1;
for (int i = 2; i <= N; i++) {
if (is_prime[i] == 0) {
is_prime[i] = i;
prime[++cnt] = i;
miu[i] = -1;
f[i] = miu[1];
}
for (int j = 1; j <= cnt; j++) {
if (i * prime[j] > N || prime[j] > is_prime[i])break;
is_prime[i * prime[j]] = prime[j];
if (i % prime[j] == 0) {
miu[i * prime[j]] = 0;
f[i * prime[j]] = miu[i];
} else {
miu[i * prime[j]] = -miu[i];
f[i * prime[j]] = miu[i] - f[i];
}
}
}
for (int i = 1; i <= N; i++)pre_f[i] = pre_f[i - 1] + f[i];
}
long long F(int a, int b) {
long long ans = 0;
for (int i = 2; i <= min(a, b);) {
int next = min(a / (a / i), b / (b / i));
ans += (long long)(a / i) * (b / i) * (pre_f[next] - pre_f[i - 1]);
i = next + 1;
}
return ans;
}
signed main() {
Primes(1e7);
int ts;
scanf("%d", &ts);
while (ts--) {
int n, m;
scanf("%d %d", &n, &m);
printf("%lld\n", F(n, m));
}
return 0;
}