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

来源:互联网 发布:阿里云香港节点ip 编辑:程序博客网 时间:2024/05/16 12:46

【poj】 2480 Longge’s problem (欧拉函数)

【题目链接】http://poj.org/problem?id=2480


题目

Description

    Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N. "Oh, I know, I know!" Longge shouts! But do you know? Please solve it. 

Input

Input contain several test case. A number N per line. 

Output

For each N, output ,∑gcd(i, N) 1<=i <=N, a line

Sample Input

26

Sample Output

315

题目大意

求小于等于n的所有正整数与n的最大公因数之和,即∑gcd(i, N) 1<=i <=N

背景知识

欧拉函数
对正整数n,欧拉函数( phi(n) )是小于n的正整数中与n互质的数的数目(φ(1)=1)。


解题思路

先打表找规律,发现对于一个n,最大公因子相同的项很多,于是考虑从因子角度来求,最大公因数为1的项的数量显然为phi(n),对于某个最大公因子为d的i来说,gcd(i,n)=d,即gcd(i/d,n/d)=1,所有与n的最大公因子为d的元素的数量为phi(n/d),(ps:如果从小到大扫一遍,i==d时就能将最大公因子为d的项全部解决掉)


AC代码

    #include<iostream>    #include<cstdio>    #include<cstring>    #include<cstdlib>    #include<string>    #include<algorithm>    #include<math.h>    #include<limits.h>    #include<stack>    #include<queue>    #define LL long long    #define maxn 50010//数据为2^31,预处理因数到5e4即可;    using namespace std;    LL prime[maxn];    LL pr[maxn]={0};//质数    void _prime()    {        LL k=0;        for(LL i=2;i<maxn;i++)        {//printf("%lld ",i);            if(prime[i]==0) pr[k++]=i;            for(LL j=0;j<k&&pr[j]*i<maxn;j++)            {                prime[pr[j]*i]=1;                if(i%pr[j]==0) break;            }             //printf("pr[%lld]=%lld ",k-1,pr[k-1]);        }        return ;    }    LL phi(LL n)//欧拉函数    {        LL ans=n;        for(int i=0;pr[i]*pr[i]<=n;i++)        {            if(n%pr[i]==0)            {                LL x=pr[i];                while(n%x==0)                    n/=x;                ans=ans/pr[i]*(pr[i]-1);            }            if(n==1) break;        }        if(n>1) ans=ans/n*(n-1);        return ans;    }    int main()    {        _prime();        LL n,ans,i,nn;        while(cin>>n)        {            nn=n;            ans=n+phi(n);            for(i=2;i*i<n;i++)            {                if(n%i==0)                {                    ans += i * phi(n/i) ;//最大公因数为i的情况;                    ans += n/i * phi(i) ;                }            }            if(i*i==n)//此时i和n/i是同一个数,只能算一次;            {                ans+=i*phi(i);            }            cout<<ans<<endl;        }        return 0;    }
阅读全文
0 0
原创粉丝点击