hdu 1286(歐拉函數 phi)

題目:

      

找新朋友

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1882 Accepted Submission(s): 903

Problem Description
新年快到了,“豬頭幫協會”準備搞一個聚會,已經知道現有會員N人,把會員從1到N編號,其中會長的號碼是N號,凡是和會長是老朋友的,那麼該會員的號碼肯定和N有大於1的公約數,否則都是新朋友,現在會長想知道究竟有幾個新朋友?請你編程序幫會長計算出來。
 
Input
第一行是測試數據的組數CN(Case number,1<CN<10000),接着有CN行正整數N(1<n<32768),表示會員人數。
 
Output
對於每一個N,輸出一行新朋友的人數,這樣共有CN行輸出。
 
Sample Input
2
25608
24027
 
Sample Output
7680
16016
 


題意爲求小於一個數的所有互質數,用歐拉公式求互質數:φ(n)=n(1-1/p1)(1-1/p2)……(1-1/pm)

n從1開始遍歷到32768,對與每個n遍歷它不大於32768的所有倍數,根據歐拉公式更新數組中的數值。n遍歷完成則所求的所有數都打好表了……直接輸出即可……

##代碼如下


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <string>
using namespace std;
#define For(i,a) for(i=0;i<a;i++)
#define Foru(i,a,b) for(i=a;i<=b;i++)
#define Ford(i,a,b) for(i=a;i>=b;i--)
#define clr(ar,vel) memset(ar,vel,sizeof(ar))
#define PB push_back
typedef long long ll;
const int maxint = 0x7fffffff;
const ll maxll = 1LL<<60;
const double EPS = 1e-10;

//	素數篩法 
const int prime_num = 32768;
int prime[prime_num], cnt;
void init(){
 	memset(prime, 0, sizeof(prime));
	for(int i = 2; i < prime_num; i ++){
		if( prime[i] ) continue;
		for(int j = i*i; j < prime_num; j += i)		prime[j] = 1;
	}
	cnt = 0;
	for(int i = 2; i < prime_num; i ++){
		if( !prime[i] ) prime[cnt++] = i;
	}
}

// 歐拉函數 phi() 
int phi(int x){
	int res = x;
	for(int i = 0; i < cnt && prime[i] <= x; i ++)	if( x % prime[i] == 0) res /= prime[i], res *= (prime[i] - 1);
	return res;
}

int main(){
	#ifndef in
	ios::sync_with_stdio(false);
	#endif
	init();
	int t, n;
	cin >> t;
	while(t--){
		cin >> n;
		int x = *lower_bound(prime, prime+cnt, n);
		if( x == n) cout << n-1 << endl;
		else cout << phi(n) << endl;
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章