求 1 <= i <= n, 1 <= j <= m 范围的 d(i * j) 的和,d(x) 为 x 的因子个数
#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
const int MAXN = 50005;
int prime[MAXN], cnt = 0, min_prime[MAXN], miu[MAXN];
int min_num[MAXN], d[MAXN], f[MAXN], pre_miu[MAXN];
inline void Primes(int n) {
miu[1] = 1, d[1] = 1;
for (int i = 2; i <= n; i++) {
if (min_prime[i] == 0) {
min_prime[i] = i;
prime[++cnt] = i;
miu[i] = -1;
min_num[i] = 1;
d[i] = 2;
}
for (int j = 1; j <= cnt; j++) {
if (prime[j] > min_prime[i] || i * prime[j] > n)break;
min_prime[i * prime[j]] = prime[j];
if (i % prime[j] == 0) {
miu[i * prime[j]] = 0;
min_num[i * prime[j]] = min_num[i] + 1;
d[i * prime[j]] = d[i] / (min_num[i] + 1) * (min_num[i * prime[j]] + 1);
} else {
miu[i * prime[j]] = -miu[i];
min_num[i * prime[j]] = 1;
d[i * prime[j]] = d[i] * 2;
}
}
}
for (int i = 1; i <= n; i++)pre_miu[i] = pre_miu[i - 1] + miu[i];
for (int i = 1; i <= n; i++)f[i] = f[i - 1] + d[i];
}
int Solve(int n, int m) {
int ans = 0;
for (int i = 1; i <= min(n, m);) {
int next = min(n / (n / i), m / (m / i));
ans += f[n / i] * f[m / i] * (pre_miu[next] - pre_miu[i - 1]);
i = next + 1;
}
return ans;
}
signed main() {
Primes(50000);
int ts;
scanf("%lld", &ts);
while (ts--) {
int n, m;
scanf("%lld %lld", &n, &m);
printf("%lld\n", Solve(n, m));
}
return 0;
}