sicily 1085. Longge's problem

/*

设F(N)=∑gcd(i, N) ,1<=i<=N
性质:F[P^k]=k×(P^k-P^(k-1))+P^k ,P为质数  (详细的证明放在后面)
且F(N)是积性函数,即当GCD(M,N)=1时,有 F[M×N]=F[M]×F[N],
又因为一个正整数总可以表示成素数(它的质因子)的乘积: 
N = p1^k1  *  p2^k2  *  ... *   pn^kn (这里p1,p2,..pn是素数,当然相互之间是互质的)
所以F(N)=F[p1^k1] * F[p2^k2] * ... * F[pn^kn] 
= (k1×(p1^k1-p1^(k1-1))+p1^k1) * (k2×(p2^k2-p2^(k2-1))+p2^k2) * ... * (kn×(pn^kn-pn^(kn-1))+pn^kn)

*/

#include 
<iostream>        //欧拉积性函数,求∑gcd(i, N) ,1<=i<=N.
#include<stdio.h>
using namespace std;
int main () 
{
    
long long n,i,phi;
    
while(scanf("%lld",&n)!=EOF)
    {
        phi
=1;
        
for(i=2;i*i<=n;++i)        //i要声明为long long,若声明为int,当i值较大时 i*i 可能会溢出        
        {    
            
if(n%i!=0)
                
continue;
            
long long p=0,t=1;    
            
while(n%i==0)    
            {
                n
=n/i;
                p
++;
                t
*=i;
            }
            phi
*=p*(t-t/i)+t;    //F[P^k]=k×(P^k-P^(k-1))+P^k (P为质数)        

        }
        
if(n!=1)    
            phi
*=2*n-1;            //n要声明为long long,若声明为int,当i值较大时 2*n 可能会溢出    
        printf("%lld\n",phi);        
    }
    
return 0;
}



/*

如果 N 可由 N=P^k 表示, P为素数,记 F[N]=∑gcd(i, N) ,1<=i<=N, 证明 F[N]=k×(P^k-P^(k-1))+P^k 
证明: 由 F[N]=∑gcd(i, N) 得 F(N)=∑pi*φ(N/pi), pi|N,  其中 pi 取值为 1 , P^1 , P^2 , P^3..., P^(k-1), P^k
欧拉函数φ(N/pi)其实就是1-N中所有满足gcd(m,N)=pi的m的个数 (这点很重要)
根据欧拉函数的性质:若 a=b^k, b为素数, 则φ(a)=(b-1)* b^(k-1)
所以对于 F(N)=∑pi*φ(N/pi) = 1*φ( P^k ) + P*φ( P^(k-1) ) + P^2 *φ( P^(k-2) ) +...P^(k-1)*φ(P) + P^k *φ(1)
F(N) = (P-1)*( P^(k-1) ) + (P-1)*(P)*( P^(k-2) ) + (P-1)* (P^2)* ( P^(k-3) ) +...+ (P-1)* ( P^(k-1) ) + P^k
可以看出 F(N)=  k * (P-1)*( P^(k-1) ) + P^k  = k×(P^k-P^(k-1))+P^k ,得证.

*/

  

posted on 2011-07-12 21:28  sysu_mjc  阅读(198)  评论(0编辑  收藏  举报

导航