1040:
给出一个n,求1-n这n个数,同n的最大公约数的和。比如:n = 6
1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15
n <= 1e9
ll get_ephi(ll n) { ll m = int(sqrt(n + 0.5)); ll ans = n; for (int i = 2; i <= m; i++) { if (n % i == 0) { ans = ans / i * (i - 1); while (n % i == 0) n /= i; } } if (n > 1) ans = ans / n * (n - 1); return ans; } int main() { ll n; scanf("%lld", &n); if (n == 1) puts("1"); else { ll res = 0; for (ll i = 1; i * i <= n; i++) { if (n % i == 0) { if (i * i == n) res += get_ephi(n / i) * i; else res += get_ephi(n / i) * i + get_ephi(i) * n / i; } } printf("%lld", res); } }
1188:
给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和。
1 <= T <= 50000
2 <= N <= 5000000
ll f[maxn]; int phi[maxn]; void phi_table(int n, int* phi) { for (int i = 2; i <= n; i++) phi[i] = 0; phi[1] = 1; for (int i = 2; i <= n; i++) if (!phi[i]) for (int j = i; j <= n; j += i) { if (!phi[j]) phi[j] = j; phi[j] = phi[j] / i * (i - 1); } } void init() { for (int i = 1; i < maxn; i++) { for (int j = 2; j < maxn; j++) { if (i * j < maxn) f[i * j] += phi[j] * i; else break; } } for (int i = 1; i < maxn; i++) f[i] += f[i - 1]; } int main() { phi_table(maxn - 3, phi); init(); int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); printf("%lld ", f[n]); } }