大致題意
計算如下式子
做法
如果只是兩個數字乘積的約數個數,那麼有公式:
當有三個數字的時候,我們同樣大膽猜測然後打表驗證,可以得到如下公式:
那麼本題就相當於計算
考慮交換求和次序,先枚舉x、y和z,然後三個相互互質可以等價於其中兩個互質,第三個數字與前兩個數字的乘積互質,於是可以轉化爲如下式子:
我們令,顯然這個是可以反演的,反演之後有:
令,這個可以用數論分塊在的時間複雜度內求出來。
那麼可以在的時間複雜度內求出來。
進而對於所有的,我們可以在的時間複雜度內預處理出來。
這樣,最後的答案就是:
直接枚舉i和j,判斷即可。總的時間複雜度爲。具體見代碼。
代碼
#include<bits/stdc++.h>
#define fi first
#define se second
#define LL long long
#define pb push_back
#define INF 0x3f3f3f3f
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
const int N = 2010;
const int mod = 1 << 30;
const int msk = mod - 1;
int a,b,c,n,tot,p[N*N],mu[N*N],f[N],s[N*N];
bool isp[N*N];
void init(int N)
{
int sz=0;
mu[1]=1;
for(int i=2;i<N;i++)
{
if(!isp[i])p[++sz]=i,mu[i]=-1;
for(int j=1;j<=sz&&(LL)i*p[j]<N;j++)
{
isp[i*p[j]]=1;
if(i%p[j]==0)
{
mu[p[j]*i]=0; break;
} else mu[p[j]*i]=-mu[i];
}
}
}
int main()
{
sccc(a,b,c);
init(a*b);
for (int d=1;d<=c;d++)
{
int n=c/d;
for (int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
f[d]=(f[d]+(n/l)*(r-l+1))&msk;
}
}
for (int i=1;i<=c;i++)
{
if (!mu[i]) continue;
int w=mu[i]*f[i]; w+=w<0?mod:0;
for (int j=i;j<=a*b;j+=i) s[j]=(s[j]+w)&msk;
}
int ans=0;
for (int i=1;i<=a;i++)
for (int j=1;j<=b;j++)
if (__gcd(i,j)==1) ans=(ans+(LL)(a/i)*(b/j)*s[i*j]&msk)&msk;
printf("%d",ans);
return 0;
}