【POJ】2480 Longge's problem(欧拉函数)

题目

传送门:QWQ

 

 

分析

题意就是求∑gcd(i, N) 1<=i <=N.。

显然$ gcd(i,n) = x $时,必然$x|n$。

所以我们枚举一下n的约数,对于每个约数x,显然$ gcd(i/x,n/x)=1$

所以我们计算一下n/x的欧拉函数就ok了。

联赛前刷水题qwq

 

 

代码

// #include <bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 7000;
ll a[maxn], top=0, p[maxn];
int fac(ll x) {
    int n=x, flag=0;
    ll end = sqrt(x);
    for(ll i=2;i<=end;i++) {
        if(x%i==0) {
            flag=1;
            a[++top] = i;
            if(i*i!=x) a[++top] = x/i;
            while(n%i==0) n/=i;
        }
    }
    if(x==2) flag=0;
    return flag;
}
ll phi(ll x) {
    ll ans = x, end = sqrt(x)+1;
    for(ll i=2;i<=end;i++) {
        if(x%i==0) {
            ans = ans / i * (i-1);
            while(x%i==0) x/=i;
        }
    }
    if(x>1) ans = ans / x * (x-1);
    return ans;
}
void Ph() {
    for(int i=2;i<maxn-10;i++) p[i]=i;
    for(ll i=2;i<maxn-10;i++) {
        if(p[i]==i) {
            for(ll j=i;j<maxn-10;j+=i) {
                p[j] = p[j] / i * (i-1);
            }
        }
    }
}
int main() {
    int n; Ph();

    while(scanf("%lld",&n)==1) {
        if(n==1){
            printf("1\n"); continue;
        }
        top=0; int q=fac(n);
        if(q == 0) {
            printf("%lld\n",phi(n)+n); continue;
        }
        sort(a+1,a+1+top);
        int pp = top;
        ll ans=phi(n)+n;
        for(int i=1;i<=pp;i++) {
            ll qwq;
            if(n/a[i] < maxn-10) qwq = p[n/a[i]];
            else qwq = phi(n/a[i]);
            ans += a[i] * qwq;
        }
        printf("%lld\n",ans);
    }
}

 

 

 

posted @ 2018-10-03 23:09  noble_(noblex)  阅读(146)  评论(0编辑  收藏  举报
/* */