很容易推出
令
然后考虑预处理g(T) 的前缀和, n<=10^7
只有线性筛
来自巨神zxyoi
半懂半懂的, 对于线性筛一些函数的问题, 先留一个坑
#include<bits/stdc++.h>
#define N 10000050
#define LL long long
using namespace std;
int g[N],T;
int prim[N], isp[N], tot, a[N], b[N];
void prework(){
g[1] = 0;
for(int i=2;i<=N-50;i++){
if(!isp[i]) prim[++tot] = i, g[i] = 1, a[i] = 1, b[i] = i;
for(int j=1;j<=tot;j++){
if(i * prim[j] > N - 50) break;
isp[i * prim[j]] = 1;
if(i % prim[j] == 0){
a[i*prim[j]] = a[i] + 1;
b[i*prim[j]] = b[i] * prim[j];
int d = i / b[i];
if(d == 1) g[i*prim[j]] = 1;
else g[i*prim[j]] = (a[i*prim[j]] == a[d]) ? -g[d] : 0;
break;
}
a[i*prim[j]] = 1;
b[i*prim[j]] = prim[j];
g[i*prim[j]] = (a[i]==1) ? -g[i] : 0;
}
}
for(int i=2;i<=N-50;i++) g[i] += g[i-1];
}
void Solve(){
int n,m; scanf("%d%d",&n,&m);
LL ans = 0;
if(n>m) swap(n,m);
for(int l=1,r;l<=n;l=r+1){
int v1 = n/l , v2 = m/l;
r = min(n/v1, m/v2);
ans += (LL)(g[r] - g[l-1]) * (LL)v1 * (LL)v2;
} printf("%lld\n",ans);
}
int main(){
prework(); scanf("%d",&T);
while(T--) Solve(); return 0;
}