BZOJ 2705: [SDOI2012]Longge的问题 [欧拉函数]

2705: [SDOI2012]Longge的问题

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 2553  Solved: 1565
[Submit][Status][Discuss]

Description

Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。

Input

一个整数,为N。

Output

一个整数,为所求的答案。

Sample Input

6

Sample Output

15

HINT

【数据范围】

对于60%的数据,0<N<=2^16。

对于100%的数据,0<N<=2^32。


 gcd(i,n)=x

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

又是欧拉函数

答案为sigma{phi(n/x)*x|x是n的约数}

这个欧拉函数需要一个个算(保存不开,也没必要)

注意枚举约数的方法,sqrt(n),特判n为平方数

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=10000;
ll n,p[N],m;
ll ans;
void fac(){
    ll s=sqrt(n);
    for(int i=1;i<=s;i++){
        if(n%i==0) p[++m]=i,p[++m]=n/i;
    }
    if(s*s==n) m--;
}
ll phi(ll n){
    ll s=sqrt(n),ans=n;
    for(ll i=2;i<=s;i++) if(n%i==0){
        ans=ans/i*(i-1);
        while(n%i==0) n/=i;
    }
    if(n>1) ans=ans/n*(n-1);
    return ans;
}
int main(){
    scanf("%lld",&n);
    fac();
    for(int i=1;i<=m;i++) ans+=phi(n/p[i])*p[i];
    printf("%lld",ans);
}

 

posted @ 2016-12-19 22:21  Candy?  阅读(360)  评论(0编辑  收藏  举报