1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include <algorithm> #include <cstdio> #include <cstring> #include <iostream> #include <map> using namespace std;
namespace BlueQuantum {
typedef long long ll;
int const N = 1e7 + 5, K = 2e3 + 5;
int n, k, m, cnt; int f[K], pri[N], mu[N], smu[N]; bool vis[N];
map<pair<int, int>, int> mp;
inline void pre() { for (int i = 1; i <= k; ++i) f[i] = f[i - 1] + (__gcd(i, k) == 1); mu[1] = 1; for (int i = 2; i < N; ++i) { if (!vis[i]) pri[++cnt] = i, mu[i] = -1; for (int j = 1, x; j <= cnt && (x = i * pri[j]) < N; ++j) { vis[x] = true; if (i % pri[j] == 0) break; mu[x] = -mu[i]; } } for (int i = 1; i < N; ++i) smu[i] = smu[i - 1] + mu[i]; }
inline int getF(int x) { return x / k * f[k] + f[x % k]; }
int getS(int x, int k) { if ((k == 1 && x < N) || (!x)) return smu[x]; if (mp[make_pair(x, k)]) return mp[make_pair(x, k)]; int res = 0; if (k == 1) { res = 1; for (int i = 2, j; i <= x; i = j + 1) { j = x / (x / i); res -= (j - i + 1) * getS(x / i, 1); } } else for (int i = 1; i * i <= k; ++i) if (k % i == 0) { if (mu[i]) res += getS(x / i, i); if (i * i != k && mu[k / i]) res += getS(x / (k / i), k / i); } return mp[make_pair(x, k)] = res; }
inline int main() { cin >> n >> m >> k; pre(); ll ans = 0, lstS = 0, curS = 0; for (int l = 1, r; l <= min(n, m); l = r + 1) { r = min(n / (n / l), m / (m / l)); curS = getS(r, k); ans += (curS - lstS) * (n / l) * getF(m / l); lstS = curS; } cout << ans; return 0; }
}
int main() { #ifndef ONLINE_JUDGE #ifdef LOCAL freopen("/tmp/CodeTmp/testdata.in", "r", stdin); freopen("/tmp/CodeTmp/testdata.out", "w", stdout); #else freopen("P1587 [NOI2016] 循环之美.in", "r", stdin); freopen("P1587 [NOI2016] 循环之美.out", "w", stdout); #endif #endif
ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL); return BlueQuantum::main(); }
|