先考虑(d(i,j,k))是啥,首先会有(d(i,j)=sum_{x|i}sum_{y|j}[gcd(x,y)=1]),可以推广得到(d(i,j,k)=sum_{x|i}sum_{y|j}sum_{z|k}[gcd(x,y)=1][gcd(y,z)=1][gcd(x,z)=1]),然后开始化式子
(sum_{i=1}^{A}sum_{j=1}^{B}sum_{k=1}^{C}sum_{x|i}sum_{y|j}sum_{z|k}[gcd(x,y)=1][gcd(y,z)=1][gcd(x,z)=1])
(sum_{i=1}^{A}sum_{j=1}^{B}sum_{k=1}^{C}sum_{x|i}sum_{y|j}sum_{z|k}sum_{a|x,a|y}mu(a)sum_{b|y,b|z}mu(b)sum_{c|z,c|x}mu(c))
(sum_{a=1}^{min(A,B)}sum_{b=1}^{min(B,C)}sum_{c=1}^{min(C,A)}mu(a)mu(b)mu(c)sum_{mathrm{lcm}(c,a)|x}sum_{mathrm{lcm}(a,b)|y}sum_{mathrm{lcm}(b,c)|z}lfloorfrac{A}{x} floorlfloorfrac{B}{y} floorlfloorfrac{C}{z} floor)
这里记(F_A(x)=sum_{x|i}lfloorfrac{A}{i} floor),(F_B(x),F_C(x))同理,可得
(sum_{a=1}^{min(A,B)}sum_{b=1}^{min(B,C)}sum_{c=1}^{min(C,A)}mu(a)mu(b)mu(c)F_A(mathrm{lcm}(c,a))F_B(mathrm{lcm}(a,b))F_C(mathrm{lcm}(b,c)))
到这个时候就可以讨论了,首先是(a=b=c)的情况,可以做到(O(n))统计;然后是(abc)中两个相等且另外一个不相等,以及三个都不相等的情况.答案的这个形式就是枚举三个不同的数,然后考虑他们两两之间的贡献,可以联想到建图,连上所有的((a,b,mathrm{lcm}(a,b)))即可套三元环计数.然后我们显然只用考虑(mu(a) eq 0,mu(b) eq 0,mathrm{lcm}(a,b)le max{A,B,C})的边,可以发现这样的边只有约(8*10^5)条,所以如果是(abc)中两个相等且和另外一个不相等的情况,就是一次枚举每条边,然后枚举这条边会对应的(aab,abb,aac,acc,bbc,bcc)六种情况;如果是(abc)都不相等,那么对应到图上就是枚举一个三元环,所以使用三元环计数即可,枚举三元环复杂度(O(|E|^{1.5})),再讨论这三个点分别(abc)中的哪个来统计答案
然后这题较卡常,首先(F_A,F_B,F_C)可以(O(nlogn))预处理;然后是建图问题,因为(mathrm{lcm}(a,b)=gcd(a,b)frac{a}{gcd(a,b)}frac{b}{gcd(a,b)}),那么只要枚举(gcd(a,b)frac{a}{gcd(a,b)}frac{b}{gcd(a,b)})并且保证他们的乘积(le max{A,B,C}),可以发现这个复杂度类似调和极数,为(O(nlog^2n));还有就是能并在一起计算的式子最好并在一起
#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
using namespace std;
const int N=1e5+10,M=N*10,mod=1e9+7;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
return x*w;
}
/*int to[M],nt[M],w[M],hd[N],tot=1;
void adde(int x,int y,int z){++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;}*/
void ad(int &x,int y){x+=y,x-=x>=mod?mod:0;}
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int prm[N],pp[N],f[N],g[N],h[N],mu[N],tt,nm[N],tn,id[N],dg[N],vs[N],te;
int n,a,b,c,ans;
void inii(int *f,int nn)
{
memset(f,0,sizeof(int)*(n+1));
for(int i=1;i<=nn;++i)
for(int j=1;i*j<=nn;++j)
ad(f[i],nn/(i*j));
}
struct node{int x,y,z;}ee[M];
vector<node> gg[N];
vector<node>::iterator i1,i2;
int main()
{
///wdnmd
mu[1]=1;
for(int i=2;i<=N-5;++i)
{
if(!pp[i]) pp[i]=1,prm[++tt]=i,mu[i]=-1;
for(int j=1;i*prm[j]<=N-5;++j)
{
if(i%prm[j]==0){pp[i*prm[j]]=pp[i]+1;break;}
pp[i*prm[j]]=1,mu[i*prm[j]]=-mu[i];
}
}
for(int i=1;i<=N-5;++i)
if(mu[i]) nm[++tn]=i,id[i]=tn;
int lt=tn,T=rd();
while(T--)
{
a=rd(),b=rd(),c=rd();
n=max(max(a,b),c);
inii(f,a),inii(g,b),inii(h,c);
tn=lt;
while(nm[tn]>n) --tn;
te=0;
memset(dg,0,sizeof(int)*(n+1))/*,memset(hd,0,sizeof(int)*(n+1)),tot=1*/;
for(int d=1;d<=n;++d)
for(int i=1;1ll*i*d<=n;++i)
for(int j=i+1;1ll*i*j*d<=n;++j)
if(mu[i*d]&&mu[j*d]&&gcd(i,j)==1) ++dg[id[i*d]],++dg[id[j*d]],ee[++te]=(node){id[i*d],id[j*d],i*j*d};
for(int i=1;i<=tn;++i) gg[i].clear();
for(int i=1;i<=te;++i)
{
int x=ee[i].x,y=ee[i].y,z=ee[i].z;
if(dg[x]>dg[y]) swap(x,y);
gg[x].push_back((node){i,y,z});
}
ans=0;
for(int x=1;x<=tn;++x)
{
for(i1=gg[x].begin();i1!=gg[x].end();++i1)
{
int i=(*i1).x,y=(*i1).y,xx=nm[x],yy=nm[y],w=(*i1).z;
vs[y]=i;
int nw=(1ll*f[xx]*g[w]%mod*h[w]+1ll*f[w]*g[xx]%mod*h[w]+1ll*f[w]*g[w]%mod*h[xx])%mod;
ad(ans,(~(mu[xx]*mu[xx]*mu[yy])?nw:mod-nw));
nw=(1ll*f[yy]*g[w]%mod*h[w]+1ll*f[w]*g[yy]%mod*h[w]+1ll*f[w]*g[w]%mod*h[yy])%mod;
ad(ans,(~(mu[xx]*mu[yy]*mu[yy])?nw:mod-nw));
}
for(i1=gg[x].begin();i1!=gg[x].end();++i1)
{
int i=(*i1).x,y=(*i1).y;
for(i2=gg[y].begin();i2!=gg[y].end();++i2)
{
int j=(*i2).x,z=(*i2).y;
if(vs[z])
{
int k=vs[z],w1=ee[i].z,w2=ee[j].z,w3=ee[k].z;
int nw=(1ll*f[w1]*g[w2]%mod*h[w3]+1ll*f[w1]*g[w3]%mod*h[w2]+1ll*f[w2]*g[w1]%mod*h[w3]+1ll*f[w2]*g[w3]%mod*h[w1]+1ll*f[w3]*g[w1]%mod*h[w2]+1ll*f[w3]*g[w2]%mod*h[w1])%mod;
ad(ans,(~(mu[nm[x]]*mu[nm[y]]*mu[nm[z]])?nw:mod-nw));
}
}
}
for(i1=gg[x].begin();i1!=gg[x].end();++i1) vs[(*i1).y]=0;
}
for(int i=1;i<=tn;++i)
{
int nw=1ll*f[nm[i]]*g[nm[i]]%mod*h[nm[i]]%mod;
ad(ans,(~(mu[nm[i]]*mu[nm[i]]*mu[nm[i]])?nw:mod-nw));
}
printf("%d
",ans);
}
return 0;
}