1. 程式人生 > >HDOJ 1787 GCD Again(尤拉函式)

HDOJ 1787 GCD Again(尤拉函式)

GCD Again

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2611    Accepted Submission(s): 1090


Problem Description Do you have spent some time to think and try to solve those unsolved problem after one ACM contest?
No? Oh, you must do this when you want to become a "Big Cattle".
Now you will find that this problem is so familiar:
The greatest common divisor GCD (a, b) of two positive integers a and b, sometimes written (a, b), is the largest divisor common to a and b. For example, (1, 2) =1, (12, 18) =6. (a, b) can be easily found by the Euclidean algorithm. Now I am considering a little more difficult problem:
Given an integer N, please count the number of the integers M (0<M<N) which satisfies (N,M)>1.
This is a simple version of problem “GCD” which you have done in a contest recently,so I name this problem “GCD Again”.If you cannot solve it still,please take a good think about your method of study.
Good Luck!

Input Input contains multiple test cases. Each test case contains an integers N (1<N<100000000). A test case containing 0 terminates the input and this test case is not to be processed.

Output For each integers N you should output the number of integers M in one line, and with one line of output for each line in input.

Sample Input 2 4 0
Sample Output 0 1 知識儲備: 一.互質的概念:

1、定義

    互質(relatively primeì)又叫互素。若N個整數的最大公因數是1,則稱這N個整數互質。

  例如8,10的最大公因數是2,不是1,因此不是整數互質。

  7,10,13的最大公因數是1,因此這是整數互質。

  5和5不互質,因為5和5的公因數有1、5。

  1和任何數都成倍數關係,但和任何數都互質。因為1的因數只有1,而互質數的原則是:只要兩數的公因數只有1時,就說兩數是互質數。1只有一個因數(所以1既不是質數(素數),也不是合數),無法再找到1和其他數的別的公因數了,所以1和任何數都互質(除0外)。

  互質數的寫法:如c與m互質,則寫作(c,m)=1。

  小學數學教材對互質數是這樣定義的:“公約數只有1的兩個數,叫做互質數。”

  這裡所說的“兩個數”是指自然數。

  “公約數只有 1”,不能誤說成“沒有公約數。”

二.尤拉函式:

1.定義:

對正整數n,尤拉函式是少於或等於n的數中與n互質的數的數目。例如euler(8)=4,因為1,3,5,7均和8互質。

2.說明:

  Euler函式表達通式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn為x的所有素因數,x是不為0的整數。

 (注意:每種質因數只一個。比如 12 = 2*2*3 那麼      φ(12) = 12 * (1-1/2) * (1-1/3)=4  )

euler(1)=1(唯一和1互質的數(小於等於)就是1本身)。 

尤拉函式性質:  1、  φ(mn) = φ(m) φ(n)

                               2、若n為奇數,φ(2n) = φ(n)。

尤拉公式的延伸:一個數的所有質因子之和是euler(n)*n/2

注意:在尤拉函式中,函式值是 [ 1 , n ] 中與 n  互質數個數

題意: 求小於n的gcd(i,n)大於1的個數  思路 : 尤拉函式直接求gcd(i,n)==1的個數  用n減即可,注意小於n,故再減去1. 具體程式碼如下:
#include<stdio.h>

int euler(int n)//尤拉函式 
{
	int res=n,i;
	for(i=2;i*i<=n;i++)
	{
		if(n%i==0)
		   res=res/i*(i-1);//先進行除法是為了防止中間資料的溢位 
		while(n%i==0)
		   n/=i;//保證n一定是素數 
	}
	if(n>1)
	   res=res/n*(n-1);
	return res;
}

int main()
{
	int n;
	while(scanf("%d",&n)&&n!=0)
	    printf("%d\n",n-euler(n)-1);//題目要求小於n,故還要減去1 
	return 0;
}