令
F(i)
表示
i
所含质因子最大幂指数,
Ans=∑T=1n⌊nT⌋⌊mT⌋∑d∣TF(d)μ(Td)
令 G(T)=∑d∣TF(d)μ(Td) ,然后我们大力讨论一下。
首先设 T=Px11×Px22×..×Pxkk,d==Py11×Py22×..×Pykk 。
要使 μ(Td)≠0 ,必须满足 yi=xi 或者 yi=xi−1 。
令 a=Max1≤i≤k(xi) ,则 F(d)=a 或 a−1 。
假设 T 中一共有
一、当
①
f(d)=a
时
∑f(d)=af(d)μ(Td)=a×∑f(d)=aμ(Td)=a×∑i=1k(−1)k−iCik=a×(−1)k+1
② f(d)=a−1 时
∑f(d)=a−1f(d)μ(Td)=(a−1)×∑f(d)=a−1μ(Td)=(a−1)×(−1)k
所以当 q=k 时, G(T)=a×(−1)k+1+(a−1)×(−1)k=(−1)k+1
二、当 q<k 时
① f(d)=a 时
∑f(d)=af(d)μ(Td)=a×∑f(d)=aμ(Td)=a×∑i=1q(−1)q−iCiq×∑j=0k−q(−1)jCjk−q=0
② f(d)=a−1 时
∑f(d)=a−1f(d)μ(Td)=(a−1)×∑f(d)=a−1μ(Td)=(a−1)×(−1)q×∑j=0k−q(−1)jCjk−q=0
所以当 q<k 时, G(T)=0
知道这些,我们可以线筛的时候记录一下最小质因子出现的次数和除去最小质因子 px11 后的数,然后判断幂指数是否相等。
#include<iostream>
#include<cstdio>
#define ll long long
#define MAXN 10000005
using namespace std;
int prime[MAXN],t[MAXN],last[MAXN];
ll g[MAXN];
bool flag[MAXN];
inline ll read()
{
ll a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void prepare()
{
for (int i=2;i<MAXN;i++)
{
if (!flag[i]) prime[++prime[0]]=i,last[i]=t[i]=g[i]=1;
for (int j=1;j<=prime[0]&&i*prime[j]<MAXN;j++)
{
flag[i*prime[j]]=1;
if (i%prime[j]==0)
{
last[i*prime[j]]=last[i];
t[i*prime[j]]=t[i]+1;
if (last[i*prime[j]]==1) g[i*prime[j]]=1;
else g[i*prime[j]]=(t[last[i*prime[j]]]==t[i*prime[j]]?-g[last[i*prime[j]]]:0);
break;
}
last[i*prime[j]]=i;
t[i*prime[j]]=1;
g[i*prime[j]]=(t[i]==1?-g[i]:0);
}
}
for (int i=1;i<MAXN;i++) g[i]+=g[i-1];
}
inline ll solve(ll n,ll m)
{
ll ans=0;
for (int i=1,pos;i<=n;i=pos+1)
{
pos=min(n/(n/i),m/(m/i));
ans+=(g[pos]-g[i-1])*(n/i)*(m/i);
}
return ans;
}
int main()
{
prepare();
int testcase=read();
while (testcase--)
{
ll n=read(),m=read();
if (n>m) swap(n,m);
printf("%lld\n",solve(n,m));
}
return 0;
}