poj 2480最大公约数和
我校OJ1110题跟poj2480题目是一样的,最大公约数和,思路挺简单,就是求出n的所有约数pi,然后f(n) = Σ(pi*Φ(n/pi))。代码打得挺乱的,POJ上1Y了,可本校OJ死活过不了,TLE,竹子出题真是变态啊,有空再优化吧,先贴个代码。
/* * poj2480/win.cpp * Created on: 2012-9-27 * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; typedef long long LL; const int MAXP = 5000; int primenum, primes[MAXP]; int pflen, primefactor[50], primefactornum[50]; int getPhi(int n) { int i, te, phi; te = (int) sqrt(n * 1.0); for (i = 2, phi = n; i <= te; i++) if (n % i == 0) { phi = phi / i * (i - 1); while (n % i == 0) { n /= i; } } if (n > 1) { phi = phi / n * (n - 1); } return phi; } void getPrimeFactor(int n) { memset(primefactornum, 0, sizeof(primefactornum)); pflen = 0; int s = (int) sqrt(n); for(int i = 0; i < primenum && primes[i] <= s; i++) { if(n % primes[i] == 0) { primefactor[pflen] = primes[i]; while(n % primes[i] == 0) { n /= primes[i]; primefactornum[pflen]++; } pflen++; } } if(n > 1) { primefactor[pflen] = n; primefactornum[pflen] = 1; pflen++; } } void init_prime_table(int N) { int i, j, s; primes[0] = 2; primenum = 1; for(i = 3; i <= N; i++) { s = (int) sqrt(i); for(j = 2; j <= s; j++) { if(i % j == 0) break; } if(j > s) { primes[primenum++] = i; } } } void dfs(int data[], int now, stack<int> &S) { if(now >= pflen) { int num = 1; for(int i = 0; i < pflen; i++) { for(int j = 0; j < data[i]; j++) { num *= primefactor[i]; } } S.push(num); return ; } data[now] = 0; for(; data[now] <= primefactornum[now]; data[now]++) { dfs(data, now + 1, S); } } LL work(int N) { getPrimeFactor(N); stack<int> S; int data[50]; dfs(data, 0, S); LL res = 0; while(!S.empty()) { int t = S.top(); res += (LL)t * getPhi(N / t); S.pop(); } return res; } int get_int() { int res = 0, ch; while (!((ch = getchar()) >= '0' && ch <= '9')) { if (ch == EOF) return -1; } res = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') res = res * 10 + (ch - '0'); return res; } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif init_prime_table(46500); int N = get_int(); while(N > 0) { printf("%lld\n", work(N)); N = get_int(); } return 0; }