学习地址
总结:莫比乌斯反演的题目是很有套路的,要学会从枚举约数到枚举倍数的改变,另外这里的约数函数的等价式需要记下。
const int N = 2e3+5;
ll mo = 1ll<< 30;
int p[N + 1], mob[N + 1], cnt,d[N][N];
bool vis[N + 1];
void x_x()
{
mob[1] = 1;
f(i, 2, N)
{
if (!vis[i])
{
p[++cnt] = i;
mob[i] = -1;
}
for (int j = 1;p[j] <= N / i;j++)
{
vis[p[j] * i] = true;
if (i%p[j] == 0)
{
mob[p[j] * i] = 0;
break;
}
mob[p[j] * i] = -mob[i];
}
}
}
int GCD(int a, int b)
{
if (d[a][b])return d[a][b];
return b ?d[a][b]= GCD(b, a%b) : a;
}
ll cal(int i, int top)
{
ll res = 0;
f(j, 1, top)
if (GCD(i, j) == 1)res = (res + top / j) % mo;
return res;
}
int main()
{
//freopen("in.txt", "r", stdin);
x_x();
int a, b, c;
while (cin >> a >> b >> c)
{
ll ans = 0;
f(i, 1, a)
f(j, 1, min(b, c))
if (GCD(i, j) == 1)
{
ll tmp = (ll)(a / i)*mob[j] * cal(i, b / j) % mo*cal(i, c / j) % mo;
ans = (ans + tmp) % mo;
}
cout << ans << endl;
}
return 0;
}