背景:
orz
\text{orz}
orz神仙题。
题意:
∑
i
=
1
a
∑
j
=
1
b
∑
k
=
1
c
d
(
i
j
k
)
\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}d(ijk)
∑i=1a∑j=1b∑k=1cd(ijk),其中
d
(
i
j
k
)
d(ijk)
d(ijk)表示
i
⋅
j
⋅
k
i\cdot j\cdot k
i⋅j⋅k的因子的个数。
思路:
大力推式子。
∑
i
=
1
a
∑
j
=
1
b
∑
k
=
1
c
d
(
i
j
k
)
\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}d(ijk)
i=1∑aj=1∑bk=1∑cd(ijk)
因为 d ( i j ) = ∑ u ∣ i ∑ v ∣ j [ gcd ( u , v ) = 1 ] d(ij)=\sum_{u|i}\sum_{v|j}[\gcd(u,v)=1] d(ij)=∑u∣i∑v∣j[gcd(u,v)=1],所以有: d ( i j k ) = ∑ u ∣ i ∑ v ∣ j ∑ w ∣ k [ gcd ( u , v , k ) = 1 ] d(ijk)=\sum_{u|i}\sum_{v|j}\sum_{w|k}[\gcd(u,v,k)=1] d(ijk)=∑u∣i∑v∣j∑w∣k[gcd(u,v,k)=1],因此:
= ∑ i = 1 a ∑ j = 1 b ∑ k = 1 c ∑ u ∣ i ∑ v ∣ j ∑ w ∣ k [ gcd ( u , v , w ) = 1 ] = ∑ i = 1 a ∑ j = 1 b ∑ k = 1 c ∑ u ∣ i ∑ v ∣ j ∑ w ∣ k [ gcd ( u , v ) = 1 ] [ gcd ( u , w ) = 1 ] [ gcd ( v , w ) = 1 ] = ∑ i = 1 a ∑ j = 1 b ∑ k = 1 c [ gcd ( i , j ) = 1 ] [ gcd ( i , k ) = 1 ] [ gcd ( j , k ) = 1 ] ⌊ a i ⌋ ⌊ b j ⌋ ⌊ c k ⌋ = ∑ i = 1 a ∑ j = 1 b ∑ k = 1 c ⌊ a i ⌋ ⌊ b j ⌋ ⌊ c k ⌋ ∑ d 1 ∣ gcd ( i , j ) μ d 1 ∑ d 2 ∣ gcd ( i , k ) μ d 2 ∑ d 3 ∣ gcd ( j , k ) μ d 3 = ∑ i = 1 a ∑ j = 1 b ∑ k = 1 c ⌊ a i ⌋ ⌊ b j ⌋ ⌊ c k ⌋ ∑ d 1 = 1 min ( a , b ) μ d 1 [ d 1 ∣ gcd ( i , j ) ] ∑ d 2 = 1 min ( a , c ) μ d 2 [ d 2 ∣ gcd ( i , k ) ] ∑ d 3 = 1 min ( b , c ) μ d 3 [ d 3 ∣ gcd ( j , k ) ] = ∑ d 1 = 1 min ( a , b ) ∑ d 2 = 1 min ( a , c ) ∑ d 3 = 1 min ( b , c ) μ d 1 μ d 2 μ d 3 ∑ i = 1 a ∑ j = 1 b ∑ k = 1 c ⌊ a i ⌋ ⌊ b j ⌋ ⌊ c k ⌋ [ d 1 ∣ gcd ( i , j ) ] [ d 2 ∣ gcd ( i , k ) ] [ d 3 ∣ gcd ( j , k ) ] = ∑ u = 1 min ( a , b ) ∑ v = 1 min ( a , c ) ∑ w = 1 min ( b , c ) μ u μ v μ w ∑ lcm(u,v) ∣ i ⌊ a i ⌋ ∑ lcm(u,w) ∣ j ⌊ b j ⌋ ∑ lcm(v,w) ∣ k ⌊ c k ⌋ \begin{aligned}&=\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}\sum_{u|i}\sum_{v|j}\sum_{w|k}[\gcd(u,v,w)=1]\\ &=\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}\sum_{u|i}\sum_{v|j}\sum_{w|k}[\gcd(u,v)=1][\gcd(u,w)=1][\gcd(v,w)=1]\\ &=\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}[\gcd(i,j)=1][\gcd(i,k)=1][\gcd(j,k)=1]\lfloor\frac{a}{i}\rfloor\lfloor\frac{b}{j}\rfloor\lfloor\frac{c}{k}\rfloor\\ &=\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}\lfloor\frac{a}{i}\rfloor\lfloor\frac{b}{j}\rfloor\lfloor\frac{c}{k}\rfloor\sum_{d1|\gcd(i,j)}\mu_{d1}\sum_{d2|\gcd(i,k)}\mu_{d2}\sum_{d3|\gcd(j,k)}\mu_{d3}\\ &=\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}\lfloor\frac{a}{i}\rfloor\lfloor\frac{b}{j}\rfloor\lfloor\frac{c}{k}\rfloor\sum_{d1=1}^{\min(a,b)}\mu_{d1}[d1|\gcd(i,j)]\sum_{d2=1}^{\min(a,c)}\mu_{d2}[d2|\gcd(i,k)]\sum_{d3=1}^{\min(b,c)}\mu_{d3}[d3|\gcd(j,k)]\\ &=\sum_{d1=1}^{\min(a,b)}\sum_{d2=1}^{\min(a,c)}\sum_{d3=1}^{\min(b,c)}\mu_{d1}\mu_{d2}\mu_{d3}\sum_{i=1}^{a}\sum_{j=1}^{b}\sum_{k=1}^{c}\lfloor\frac{a}{i}\rfloor\lfloor\frac{b}{j}\rfloor\lfloor\frac{c}{k}\rfloor[d1|\gcd(i,j)][d2|\gcd(i,k)][d3|\gcd(j,k)]\\ &=\sum_{u=1}^{\min(a,b)}\sum_{v=1}^{\min(a,c)}\sum_{w=1}^{\min(b,c)}\mu_u\mu_v\mu_w\sum_{\text{lcm(u,v)}|i}\lfloor\frac{a}{i}\rfloor\sum_{\text{lcm(u,w)}|j}\lfloor\frac{b}{j}\rfloor\sum_{\text{lcm(v,w)}|k}\lfloor\frac{c}{k}\rfloor\end{aligned} =i=1∑aj=1∑bk=1∑cu∣i∑v∣j∑w∣k∑[gcd(u,v,w)=1]=i=1∑aj=1∑bk=1∑cu∣i∑v∣j∑w∣k∑[gcd(u,v)=1][gcd(u,w)=1][gcd(v,w)=1]=i=1∑aj=1∑bk=1∑c[gcd(i,j)=1][gcd(i,k)=1][gcd(j,k)=1]⌊ia⌋⌊jb⌋⌊kc⌋=i=1∑aj=1∑bk=1∑c⌊ia⌋⌊jb⌋⌊kc⌋d1∣gcd(i,j)∑μd1d2∣gcd(i,k)∑μd2d3∣gcd(j,k)∑μd3=i=1∑aj=1∑bk=1∑c⌊ia⌋⌊jb⌋⌊kc⌋d1=1∑min(a,b)μd1[d1∣gcd(i,j)]d2=1∑min(a,c)μd2[d2∣gcd(i,k)]d3=1∑min(b,c)μd3[d3∣gcd(j,k)]=d1=1∑min(a,b)d2=1∑min(a,c)d3=1∑min(b,c)μd1μd2μd3i=1∑aj=1∑bk=1∑c⌊ia⌋⌊jb⌋⌊kc⌋[d1∣gcd(i,j)][d2∣gcd(i,k)][d3∣gcd(j,k)]=u=1∑min(a,b)v=1∑min(a,c)w=1∑min(b,c)μuμvμwlcm(u,v)∣i∑⌊ia⌋lcm(u,w)∣j∑⌊jb⌋lcm(v,w)∣k∑⌊kc⌋
设
f
y
(
x
)
=
∑
x
∣
i
⌊
y
i
⌋
f_y(x)=\sum_{x|i}\lfloor\frac{y}{i}\rfloor
fy(x)=∑x∣i⌊iy⌋,因此有:
=
∑
u
=
1
min
(
a
,
b
)
∑
v
=
1
min
(
a
,
c
)
∑
w
=
1
min
(
b
,
c
)
μ
u
μ
v
μ
w
f
a
(
lcm
(
u
,
v
)
)
f
b
(
lcm
(
u
,
w
)
)
f
c
(
lcm
(
v
,
w
)
)
=\sum_{u=1}^{\min(a,b)}\sum_{v=1}^{\min(a,c)}\sum_{w=1}^{\min(b,c)}\mu_u\mu_v\mu_wf_a(\text{lcm}(u,v))f_b(\text{lcm}(u,w))f_c(\text{lcm}(v,w))
=u=1∑min(a,b)v=1∑min(a,c)w=1∑min(b,c)μuμvμwfa(lcm(u,v))fb(lcm(u,w))fc(lcm(v,w))
我们可以预处理出
f
a
f_a
fa。
但是好像时间复杂度还是
3
3
3次方级别。
考虑什么时候没有贡献:
[
1
]
[1]
[1]:
μ
u
=
0
\mu_u=0
μu=0或
μ
v
=
0
\mu_v=0
μv=0或
μ
w
=
0
\mu_w=0
μw=0;
[
2
]
[2]
[2]:
lcm
(
u
,
v
)
>
a
\text{lcm}(u,v)>a
lcm(u,v)>a或
lcm
(
u
,
w
)
>
b
\text{lcm}(u,w)>b
lcm(u,w)>b或
lcm
(
v
,
w
)
>
c
\text{lcm}(v,w)>c
lcm(v,w)>c。
怎么去除这两种废掉的情况呢?
设
u
=
k
x
,
v
=
k
y
u=kx,v=ky
u=kx,v=ky,保证
u
⊥
v
u⊥v
u⊥v。若
μ
u
≠
0
,
μ
v
≠
0
\mu_u≠0,\mu_v≠0
μu=0,μv=0,且
lcm
(
u
,
v
)
=
k
x
y
≤
max
(
a
,
b
,
c
)
\text{lcm}(u,v)=kxy≤\max(a,b,c)
lcm(u,v)=kxy≤max(a,b,c),则连边
u
,
v
u,v
u,v。
最后我们三元环计数(据说建边用
vector
\text{vector}
vector存储更快,因为访问连续的一段内存)即可。
代码:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define LL long long
#define mod 1000000007
using namespace std;
struct node{int u,v,lcm;} da[1000010];
vector <node> F[100010];
int prime[100010],mu[100010],vis[100010];
LL f[3][100010];
bool bz[100010];
int du[100010];
int a,b,c,len=0;
LL ans;
void init(int ma)
{
bz[0]=bz[1]=true;
mu[1]=1;
int t=0;
for(int i=2;i<=ma;i++)
{
if(!bz[i]) prime[++t]=i,mu[i]=-1;
for(int j=1;j<=t&&i*prime[j]<=ma;j++)
{
bz[i*prime[j]]=true;
if(!(i%prime[j]))
{
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
}
void clear(int limit)
{
ans=0;
len=0;
for(int i=1;i<=limit;i++)
{
f[0][i]=f[1][i]=f[2][i]=0;
du[i]=0;
F[i].clear();
}
}
void init_f(int op)
{
int limit=(op==0?a:op==1?b:c);
for(int i=1;i<=limit;i++)
for(int j=i;j<=limit;j+=i)
f[op][i]=(f[op][i]+limit/j)%mod;
}
void work_3(int limit)
{
for(int i=1;i<=limit;i++)
if(mu[i]) ans=(ans+(LL)mu[i]*mu[i]*mu[i]*f[0][i]*f[1][i]*f[2][i]%mod)%mod,ans=(ans+mod)%mod;
}
void work_2(int limit)
{
for(int k=1;k<=limit;k++)
for(int x=1;(LL)x*k<=limit;x++)
if(mu[k*x])
for(int y=x+1;(LL)x*y*k<=limit;y++)
if(mu[k*y]&&__gcd(x,y)==1)
{
int u=x*k,v=y*k,lcm=x*y*k;
ans=(ans+(LL)mu[u]*mu[u]*mu[v]*((f[0][u]*f[1][lcm]*f[2][lcm])%mod+(f[0][lcm]*f[1][u]*f[2][lcm])%mod+(f[0][lcm]*f[1][lcm]*f[2][u])%mod))%mod;
ans=(ans+mod)%mod;
ans=(ans+(LL)mu[v]*mu[v]*mu[u]*((f[0][v]*f[1][lcm]*f[2][lcm])%mod+(f[0][lcm]*f[1][v]*f[2][lcm])%mod+(f[0][lcm]*f[1][lcm]*f[2][v])%mod))%mod;
ans=(ans+mod)%mod;
du[u]++,du[v]++;
da[++len]=(node){u,v,lcm};
}
}
void work_0(int limit)
{
for(int i=1;i<=len;i++)
{
int u=da[i].u,v=da[i].v,lcm=da[i].lcm;
if((du[u]>du[v])||(du[u]==du[v]&&u<v)) F[u].push_back((node){u,v,lcm}); else F[v].push_back((node){v,u,lcm});
}
for(int u=1;u<=limit;u++)
{
if(!mu[u]) continue;
for(int i=0;i<F[u].size();i++) vis[F[u][i].v]=F[u][i].lcm;
for(int i=0;i<F[u].size();i++)
{
int v=F[u][i].v,uv=F[u][i].lcm;
if(!mu[v]) continue;
for(int j=0;j<F[v].size();j++)
{
int w=F[v][j].v,vw=F[v][j].lcm,uw=vis[w];
if(!mu[w]||!vis[w]) continue;
ans=(ans+mu[u]*mu[v]*mu[w]*((f[0][uv]*f[1][uw]*f[2][vw])%mod+(f[0][uv]*f[1][vw]*f[2][uw])%mod+
(f[0][uw]*f[1][uv]*f[2][vw])%mod+(f[0][uw]*f[1][vw]*f[2][uv])%mod+
(f[0][vw]*f[1][uw]*f[2][uv])%mod+(f[0][vw]*f[1][uv]*f[2][uw])%mod)%mod)%mod;
ans=(ans+mod)%mod;
}
}
for(int i=0;i<F[u].size();i++) vis[F[u][i].v]=0;
}
}
int main()
{
int T;
init(100000);
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d",&a,&b,&c);
int ma=max(max(a,b),c);
clear(ma);
init_f(0),init_f(1),init_f(2);
work_3(ma);
work_2(ma);
work_0(ma);
printf("%lld\n",ans);
}
}