显然(我觉得不),对于点 ((i, j)) 与 ((0, 0)) 的连线,连线上点的数量是 (gcd(i, j))
那么问题转化为 (displaystyle sum_{i=1}^{N} sum_{j=1}^{M} (2 cdot (i, j) -1))
那么我们可以设(一下均令 (N le M) ) (f_{x}) 为 (x) 及其倍数 在上述和式中作为 ((i, j)) 的出现次数。令 (g_{x}) 为 恰好(x) 在和式中作为 ((i, j)) 出现的次数。
那么可得 (displaystyle sum_{i=1}^{lfloor frac{N}{d} floor} f_{i} = lfloor frac{N}{d} floor cdot lfloor frac{M}{d} floor)
因为容斥(g_{x} = f_{x} - displaystyle sum_{i=2}^{lfloor frac{N}{x} floor} f_{i cdot x})
然后暴力计算,复杂度 (O(NlogN))
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll MAXN = 1000010;
ll vis[MAXN], N, M, ans;
int main() {
scanf("%lld%lld", &N, &M);
if (N > M) swap(N, M);
for (ll d = 1; d <= N; d++) {
vis[d] = (N / d) * (M / d);
}
for (ll i = N; i >= 1; i--) {
for (ll j = 2; j <= N / i; j++) vis[i] -= vis[i * j];
ans += (vis[i] * (i * 2 - 1));
}
printf("%lld
", ans);
return 0;
}