【SDOI2012】 Longgue的问题

【题目链接】

          点击打开链接

【算法】

           gcd(i,n)是n的约数

           不妨设gcd(i,n) = d

           考虑枚举d和gcd(i,n) = d有多少个

           gcd(i,n) = d

           gcd(i/d,n/d) = 1

           因为i<=n,所以i/d<=n/d

           因此满足gcd(i,n) = d一共有phi(n/d)个

【代码】

          

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll i,n,ans;

template <typename T> inline void read(T &x) {
        ll f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
}
template <typename T> inline void write(T x) {
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x/10);
    putchar(x%10+'0');
}
template <typename T> inline void writeln(T x) {
    write(x);
    puts("");
}

ll phi(ll x) {
        ll i,ret=x;
        for (i = 2; i <= sqrt(x); i++) {
                if (x % i == 0) {
                        while (x % i == 0) x /= i;
                        ret = ret / i * (i - 1);
                }
        }    
        if (x > 1) ret = ret / x * (x - 1);
        return ret; 
} 

int main() {
        
        read(n);
        for (i = 1; i <= sqrt(n); i++) {
                    if (n % i == 0) {
                            ans += phi(n/i) * i;
                            if (i * i != n) ans += phi(i) * n / i;
                    }
        }
        
        writeln(ans);
        
        return 0;
    
}

 

posted @ 2018-03-20 21:30  evenbao  阅读(112)  评论(0编辑  收藏  举报