∑isprime(p)∑na=1∑mb=1gcd(a,b)==p
∑isprime(p)∑⌊np⌋a=1∑⌊mp⌋b=1gcd(a,b)==1
∑isprime(p)∑⌊np⌋a=1∑⌊mp⌋b=1∑d|gcd(a,b)μ(d)
∑isprime(p)∑⌊np⌋a=1∑⌊mp⌋b=1∑d|a∧d|bμ(d)
∑isprime(p)∑⌊np⌋d=1μ(d)⌊npd⌋⌊mpd⌋
令
k=pd
∑nk=1∑isprime(p)∧p|kμ(kp)⌊nk⌋⌊mk⌋
令
F(k)=∑isprime(p)∧p|kμ(kp)
∑nk=1F(k)⌊nk⌋⌊mk⌋
线性筛出
μ
然后枚举质数的倍数 复杂度约是
#include<bits/stdc++.h>
#define inf 1000000000
#define ll long long
using namespace std;
const int N=1e7+5;
const int M=1e6+5;
int T,n,m,cnt;
bool mark[N];
int pri[M],mu[N];
ll f[N];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void getphi() {
mu[1]=1;
for(int i=2; i<N; i++) {
if(!mark[i])pri[++cnt]=i,mu[i]=-1;
for(int j=1; j<=cnt&&pri[j]*i<N; j++) {
mark[i*pri[j]]=1;
if(i%pri[j]==0) {
mu[i*pri[j]]=0;
break;
} else mu[i*pri[j]]=-mu[i];
}
}
for(int i=1; i<=cnt; i++) {
int p=pri[i];
for(int j=1; j*p<N; j++)f[j*p]+=mu[j];
}
for(int i=1; i<N; i++)f[i]+=f[i-1];
}
int main() {
getphi(),T=read();
while(T--) {
ll ans=0;
n=read(),m=read();
if(n>m)swap(n,m);
for(int i=1,j; i<=n; i=j+1) {
j=min(n/(n/i),m/(m/i));
ans+=(f[j]-f[i-1])*(n/i)*(m/i);
}
printf("%lld\n",ans);
}
return 0;
}