poj 2480 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-22 20:33  sysu_mjc  阅读(138)  评论(0编辑  收藏  举报

导航