1085.Longge's problem (数论,欧拉积性函数)

来源:互联网 发布:软件项目流程 编辑:程序博客网 时间:2024/06/06 00:28
  

Longge's problem


Time Limit:1000MS   Memory Limit:65536K
Total Submit:1156 Accepted:308

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


2
6

Sample Output


3
15

 

好的,开始分析。

首先看什么是欧拉函数:

关于形式为\phi(q)=\prod_{k=1}^\infty (1-q^k)的函数,在数论中,对正整数n,欧拉函数φ(n)是小于或等于n的正整数中与n互质的数的数目。

显然,对于素数p,φ(p)= p -1.对于两个素数p、q,他们的乘积n = pq 满足φ(n) =(p-1)(q-1)。下面证明:

          证明:对于质数p,q,满足φ(n) =(p-1)(q-1)
         考虑n的完全余数集Zn = { 1,2,....,pq -1}
         而不和n互质的集合由下面三个集合的并构成:
         1) 能够被p整除的集合{p,2p,3p,....,(q-1)p} 共计q-1个
         2) 能够被q整除的集合{q,2q,3q,....,(p-1)q} 共计p-1个
         3) {0}
         很显然,1、2集合中没有共同的元素,因此Zn中元素个数 = pq - (p-1 + q- 1 + 1) = (p-1)(q-1)

由此应该可以理解欧拉函数的积性性质:只要gcd(m,n)=1,则必有φ(m*n)=φ(m)*φ(n)。

理解一个句子:φ(N/pi)就是1~N中所有满足gcd(s,N)=pi的s的个数。仔细体会。

再理解一个句子,不难理解:一个正整数总可以表示成素数(它的质因子)的乘积: N = p1^k1  *  p2^k2  *  ... *   pn^kn (这里p1,p2,..pn是素数,当然相互之间是互质的)

再理解一个性质,做好准备:φ(pi^k)=pi*\(pi^(k-1))=pi^(k-1)*φ(pi)=(pi-1)*pi^(k-1),pi为质数。

回到题目,设F(N)=∑gcd(i, N) ,1<=i<=N.

下面考虑一个命题:如果 N 可由 N=P^k 表示,(为什么要用P^k表示后面就知道了) P为素数,那么:

                  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 ,得证.

回忆前文,一个正整数总可以表示成素数的乘积:
N = p1^k1  p2^k2  ... *   pn^kn
所以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<cstdio>int main (){    long long n,i,phi;    while(scanf("%lld",&n)!=EOF)    {        phi=1;        for(i=2;i*i<=n;++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;                      printf("%lld\n",phi);           }    return 0;}


原创粉丝点击