题意
A,B,C≤1e7A,B,C≤1e7
∑i=1A∑j=1B∑k=1Cϕ(gcd(i,j2,k3))∑i=1A∑j=1B∑k=1Cϕ(gcd(i,j2,k3))
题解
很难受 写这题的时候真是又困又难受,冷静下来细想并没有那么难qwq
学计算机果然要身体好才行呀
对于这个东西,我们先想到把 phiphi 和 gcdgcd 拆开。
设 f(d)f(d) 表示存在多少个 i,j,ki,j,k 使得 d|gcd(i,j2,k3)d|gcd(i,j2,k3)
设 g(d)g(d) 表示存在多少个 i,j,ki,j,k 使得 d==gcd(i,j2,k3)d==gcd(i,j2,k3)
我们先不考虑怎么求 f,gf,g
那么 ans=∑g(d)∗ϕ(d)ans=∑g(d)∗ϕ(d)
容易发现
f(d)=∑d|kg(k)f(d)=∑d|kg(k)
然后我们莫比乌斯一下
g(d)=∑d|kμ(k/d)∗f(k)g(d)=∑d|kμ(k/d)∗f(k)
再把这个带入 ansans
ans=∑ϕ(d)∗∑d|kf(k)∗μ(k/d)ans=∑ϕ(d)∗∑d|kf(k)∗μ(k/d)
=∑kf(k)∑d|kϕ(d)∗μ(k/d)=∑kf(k)∑d|kϕ(d)∗μ(k/d)
两个积性函数的狄利克雷卷积还是积性函数,后面这部分可以搞一搞线筛出来。
前面这一部分也好算f(k)=Ak∗Bb[k]∗Cc[k]f(k)=Ak∗Bb[k]∗Cc[k]
b[k]为最小的x使得 x∗x%k==0x∗x%k==0
c[k]同理
然后b[k],c[k]也是积性函数,线筛搞搞就可以了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const int maxn = 1e7 + 10;
const int mod = 1<<30;
int prm[maxn], phi[maxn], tot;
bool ok[maxn];
ui bb[maxn], cc[maxn], sx[maxn], fck[maxn];
void get_prime(int n){
tot = 0;
memset(ok, 0, sizeof(ok)); phi[1] = 1;
cc[1] = bb[1] = 1;
sx[1] = 1;
for (int i = 2; i <= n; i ++){
if (!ok[i]){
prm[++ tot] = i;
phi[i] = i - 1;
cc[i] = bb[i] = i;
sx[i] = i - 2;
fck[i] = i;
}
for (int j = 1; j <= tot; j ++){
if (1LL * i * prm[j] > n) break;
if (1LL * bb[i] * bb[i] % (i * prm[j]) == 0)
bb[i * prm[j]] = bb[i];
else bb[i * prm[j]] = bb[i] * prm[j];
if (1LL * cc[i] * cc[i] % (i * prm[j]) * cc[i] % (i * prm[j]) == 0)
cc[i * prm[j]] = cc[i];
else cc[i * prm[j]] = cc[i] * prm[j];
ok[i * prm[j]] = true;
if (i % prm[j]){
phi[i * prm[j]] = phi[i] * phi[prm[j]];
sx[i * prm[j]] = sx[i] * sx[prm[j]];
fck[i * prm[j]] = prm[j];
}
else{
phi[i * prm[j]] = phi[i] * prm[j];
sx[i * prm[j]] = sx[i / fck[i]] * (phi[fck[i] * prm[j]] - phi[fck[i]]);
fck[i * prm[j]] = fck[i] * prm[j];
break;
}
}
}
}
bool nsp[maxn];
void prepare(){
get_prime(maxn - 1);
}
void work(){
ui A,B,C;
scanf("%u%u%u", &A, &B, &C);
ui qwq = 0;
for (int i = A; i; i --){
qwq = qwq + 1LL * (A / i) * (B / bb[i]) * (C / cc[i]) * sx[i];
}
printf("%u\n", qwq % mod);
}
int main(){
prepare();
int T; scanf("%d", &T);
while (T --)
work();
return 0;
}