定义
令
需要在不高于线性时间内预处理出
在没有什么思路的情况下, 在看题解 (弃疗) 之前, 我选择用
首先, 发现所有
发现质数和质数的幂的
和莫比乌斯函数表放在一起看, 没有发现什么.
对取每个值的数做一做质因数分解.
线性筛, 记录
学习了一下题解. 对
方便起见, 我们把对象从整数转换到集合. 设
我们有以下关系式:
这和
注意到
当
typedef long long ll;
const int N = 1e7;
int f[N+1], g[N+1], h[N+1];
void sieve()
{
static bool v[N+1];
static int p[N+1], ptr;
rep (i, 2, N+1)
{
if (!v[i])
{
h[i] = f[i] = 1;
g[i] = i;
p[ptr++] = i;
}
for (int j = 0, t; j < ptr && (t = i*p[j]) <= N; ++j)
{
v[t] = true;
if (i % p[j])
{
f[t] = 1;
g[t] = p[j];
h[t] = f[i] == 1 ? -h[i] : 0;
}
else
{
f[t] = f[i] + 1;
g[t] = g[i] * p[j];
h[t] = g[t] == t ? 1 : (f[i/g[i]] == f[i] + 1 ? -h[i/g[i]] : 0);
break;
}
}
}
rep (i, 2, N+1)
h[i] += h[i-1];
}
ll solve(int a, int b)
{
ll ans = 0;
for (int i = 1, j, c = min(a, b); i <= c; i = j+1)
{
int _a = a/i, _b = b/i;
j = min(a/_a, b/_b);
ans += 1LL * _a * _b * (h[j] - h[i-1]);
}
return ans;
}
int main()
{
sieve();
int T;
scanf("%d", &T);
while (T--)
{
int a, b;
scanf("%d%d", &a, &b);
printf("%lld\n", solve(a, b));
}
return 0;
}