uva 11317,
題目連結:uva 11317 - GCD+LCM
題目大意:給定n,求出1~n裡面兩兩的最大公約的積GCD和最小公倍數的積LCM,在10100進位下的位元。
解題思路:在n的情況下,對於最大公約數為i的情況又phi[n/i]次。求LCM就用兩兩乘積除以GCD即可。
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 1000000;const double logt = log(10.0);int N;double g[maxn+5], s[maxn+5];int phi[maxn+5];void phi_table (int n) { memset(phi, 0, sizeof(phi)); 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 (ll n) { for (int i = 1; i <= n; i++) { double tmp = log(i); for (int j = 2 * i; j <= n; j += i) g[j] += phi[j/i] * tmp; } for (int i = 1; i <= n; i++) g[i] += g[i-1]; for (int i = 1; i <= n; i++) g[i] /= logt;}int main () { phi_table(maxn); init(maxn); int cas = 1; while (scanf("%d", &N) == 1 && N) { double ans = 0; for (int i = 1; i <= N; i++) ans += (N-1) * log(i); ans /= logt; ans -= g[N]; printf("Case %d: %lld %lld\n", cas++, (ll)(g[N] / 100) + 1, (ll)(ans / 100) + 1); } return 0;}