解题思路:莫比乌斯反演+分块思想。
模板:
#include<bits/stdc++.h>
#define lowbit(x) ((x)&(-(x)))
#define ll long long
#define INF 0x3f3f3f3f
#define CLR(a) memset(a, 0, sizeof(a))
using namespace std;
const int N=1e7+10;
int t,n,m,cnt;
bool vis[N];
int mu[N],g[N],prim[N];
ll sum[N];
void get_mu(int n){//得到莫比乌斯函数值
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prim[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prim[j]<=n;j++){
vis[i*prim[j]]=1;
if(i%prim[j]==0) break;
else mu[i*prim[j]]=-mu[i];
}
}
for(int j=1;j<=cnt;j++)
for(int i=1;i*prim[j]<=n;i++) g[i*prim[j]]+=mu[i];
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+(ll)g[i];
}
int main() {
scanf("%d",&t);
get_mu(1e7);
while(t--){
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
ll ans=0;
//分块查找
for(int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]);
}
printf("%lld\n",ans);
}
return 0;
}