欧拉函数 BZOJ2705

2705: [SDOI2012]Longge的问题

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 3154  Solved: 1968
[Submit][Status][Discuss]

Description

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

Input

一个整数,为N。

Output

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

Sample Input

6

Sample Output

15
 
枚举n的因子,对于一个因子x,求与n只有这一个因子x的数目,显然如果暴力的话就是for(int i=x;i<=n;i+=x)然后判断每个i是否与n只有一个因子,从而求得数目然后乘上x。
可以用欧拉函数简化这一过程,因子为x,那么与他成对那个就是y=n/x。我们只需求出小于y并与y互质的数目就可以了,因为与y互质,那么与k*y(显然ky可以等于n)仍然互质,也就是说找出来的每个z。必定满足gcd(n,z)==1且z*x<n,那么gcd(n,z*x)肯定就只有x这一个因子了,从而简化了过程
 
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL phi(LL x)
{
    LL ans=x;
    for(LL i=2; i*i<=x; ++i)
    {
        if(x%i==0) ans=ans*(i-1)/i;
        while(x%i==0) x/=i;
    }
    if(x>1) ans=ans*(x-1)/x;
    return  ans;
}
int main()
{
    LL n;
    scanf("%lld",&n);
    LL ans=0;
    for(LL i=sqrt(n); i>=1; --i)
    {
        if(n%i==0)
        {
            ans+=phi(n/i)*i;
            if(i*i!=n) ans+=phi(i)*(n/i);
        }
    }
    printf("%lld\n",ans);
}

 

posted @ 2017-08-16 01:03  Billyshuai  阅读(125)  评论(0编辑  收藏  举报