学习数论之莫比乌斯反演、杜教筛推荐:peng-ym
推理:
令:
我们要求的是:
令
显然F(x)很容易求:
我们反演一下:
假设n<=m,我们变一下形:
枚举所有质数的所有倍数是不是可以换成枚举所有数的所有质因数,ok,我再变形:
由于F(T)怎么求前面已经得知,所有我只用打表,然后用整除分块即可,这题就完美解决了。
注意一个超时的坑点:定义long long 类型的n,m会超时。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e7+10;
int prim[maxn],vis[maxn],mu[maxn],cnt;
ll g[maxn];
void get_mu(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i])
mu[i]=-1,prim[++cnt]=i;
for(int j=1;j<=cnt&&prim[j]*i<=n;j++)
{
vis[i*prim[j]]=1;
if(i%prim[j]==0)break;
else mu[prim[j]*i]=-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++)
g[i]=g[i-1]+g[i];
}
int main()
{
int T,l,r,n,m;
get_mu(1e7);
scanf("%d",&T);
while(T--)
{
ll ans=0;
scanf("%d%d",&n,&m);
if(n>m)swap(n,m);
for(int l=2;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ans+=1ll*n/l*(m/l)*(g[r]-g[l-1]);
}
printf("%lld\n",ans);
}
}