枚举质数
p
,可以得到
令 T=pt ,原式可以化为
∑T=1min(n,m)[nT][mT]∑p|Tμ(Tp)
后面一部分我们暴力枚举质数 p <script type="math/tex" id="MathJax-Element-243">p</script>即可得到
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
typedef long long LL;
int miu[11000000];
int prim[11000000],primm;
bool valid[11000000];
void mobius(int N)
{
miu[1]=1;
for (int i=2;i<=N;i++)
{
if (!valid[i]) prim[++primm]=i,miu[i]=-1;
for (int j=1;j<=primm&&i*prim[j]<=N;j++)
{
valid[i*prim[j]]=1;
if (i%prim[j]==0)
{
miu[i*prim[j]]=0;
break;
}
else miu[i*prim[j]]=-miu[i];
}
}
}
int T,n,m;
LL sum[11000000];
LL F(int n,int m)
{
LL res=0;
for (LL i=1;i<=min(n,m);i++)
{
int pos=i;
i=min(n/(n/i),m/(m/i));
LL a=n/i,b=m/i;
res+=a*b*(sum[i]-sum[pos-1]);
}
return res;
}
int main()
{
mobius(10000000);
for (int i=1;i<=primm;i++)
for (int j=1;j*prim[i]<=10000000;j++)
sum[prim[i]*j]+=miu[j];
for (int i=1;i<=10000000;i++)
sum[i]+=sum[i-1];
scanf("%d",&T);
while (T--)
{
scanf("%d %d",&n,&m);
LL ans=F(n,m);
printf("%lld\n",ans);
}
return 0;
}