几道GCD相关题目总结

几道GCD相关题目总结

修改自: http://hi.baidu.com/arorua_/item/381bb88d817b122d100ef3a1
Number one:poj2480  http://poj.org/problem?id=2480
题意是:求 ∑gcd(i, N) 1<=i <=N.   N(1 < N < 2^31)
解法: gcd(i, n) ==  ∑(fac[i] * phi(n / fac[i])) (fac存的是n的所有约数)
代码:
poj2480
//sigma(gcd(i, n)) == sigma(fac[i] * phi(n / fac[i]))

#include <cstdio>
#include <cstring>
using namespace std;

long long n, ans;
int fac[32000], cnt;

//get eular
long long get_eular(long long n) {
    long long res = 1;
    for (long long i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            n /= i; res = res * (i - 1);
            while (n % i == 0) {
                n /= i; res = res * i;
            }
        }
    }
    if (n > 1) res *= n - 1;
    return res;
}

void get_factor(long long n) {
    cnt = 0;
    memset(fac, 0, sizeof(fac));
    for (int i = 1; (long long)i * i <= n; i++) {
        if (n % i == 0) {
            if (i * i == n) {
                fac[cnt++] = i; return ;
            }
            fac[cnt++] = i;
            fac[cnt++] = n / i;
        }
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("p2480", "r", stdin);
#endif

    while (scanf("%lld", &n) != EOF) {
        ans = 0;
        get_factor(n);
        for (int i = 0; i < cnt; i++)
            ans += fac[i] * (get_eular(n / fac[i]));
        printf("%lld\n", ans);
    }
    return 0;
}



你可能感兴趣的:(几道GCD相关题目总结)