http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=10581
∑i=1n∑j=1mgcd(i,j)==质数另f(x)为gcd(i,j)=x的对数f(x)=∑x|dμ(d/x)∗(n/d)∗(m/d)ans=∑p,p为质数min(n,m)∗f(p)=∑p,p为质数min(n,m)∗∑dμ(d)∗⌊np∗d⌋∗⌊mp∗d⌋另T=p∗dans=∑T=2min(n,m)(n/T)∗(m/T)∗∑p|T,p为质数μ(T/p)另sum(x)=∑p|xμ(x/p)ans=∑T=2min(n,m)(n/T)∗(m/T)∗sum(T)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e7+100;
typedef long long LL;
int pri[N],p[N],pn,mu[N];
LL sum[N];
void init(){
pn=0;memset(p,0,sizeof(p));
int n=1e7;
mu[1]=1;sum[1]=1;sum[0]=0;p[1]=1;
for(int i=2;i<=n;i++){
if(!p[i]){
mu[i]=-1;
sum[i]=1;
pri[pn++]=i;
}
for(int j=0;j<pn;j++){
if((LL)i*pri[j]>n)break;
p[i*pri[j]]=1;
if(i%pri[j]==0){
mu[i*pri[j]]=0;
sum[i*pri[j]]=mu[i];
break;
}
else {
mu[i*pri[j]]=-mu[i];
sum[i*pri[j]]=mu[i]-sum[i];
}
}
}
for(int i=1;i<=n;i++){
sum[i]+=sum[i-1];
}
}
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
int T;scanf("%d",&T);
init();
while(T--){
int a,b;scanf("%d%d",&a,&b);
int r=min(a,b);
LL ans=0;
while(r>1){
int k1=a/r;
int k2=b/r;
int l1=a/(k1+1)+1;
int l2=b/(k2+1)+1;
int l=max(l1,l2);
l=max(l,2);
ans+=(LL)k1*k2*(sum[r]-sum[l-1]);
r=l-1;
}
printf("%lld\n",ans);
}
return 0;
}