题目描述
题解
这题和上一题差不多的…
令
利用反演公式
令
令
直接求
如何预处理
考虑线性筛,但是求
但是我们仍然可以用类似线性筛的方法求出
观察
咦这和
显然当n为质数时
考虑用
1° 当
2° 当
3° 当
这样求出
分块之后
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 10000005
#define LL long long
#define Mod 1000000007
int T,n,m;
int p[N],prime[N],mu[N],f[N];
LL ans;
void get(int n)
{
mu[1]=1;f[1]=0;
for (int i=2;i<=n;++i)
{
if (!p[i])
{
prime[++prime[0]]=i;
f[i]=1;
mu[i]=-1;
}
for (int j=1;j<=prime[0]&&i*prime[j]<=n;++j)
{
p[i*prime[j]]=1;
if (i%prime[j]==0)
{
mu[i*prime[j]]=0;
if (mu[i]) f[i*prime[j]]=mu[i];
else f[i*prime[j]]=0;
break;
}
else
{
mu[i*prime[j]]=-mu[i];
f[i*prime[j]]=-f[i]+mu[i];
}
}
}
for (int i=1;i<=n;++i) f[i]+=f[i-1];
}
int main()
{
get(10000000);
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
if (n>m) swap(n,m);
ans=0;
for (int i=1,j=0;i<=n;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans+=(LL)(n/i)*(m/i)*(f[j]-f[i-1]);
}
printf("%lld\n",ans);
}
}