/*
Name:小於n且與n互素的個數(歐拉函數)
Actor:HT
Time:2015年8月10日
Error Reporte:
*/
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <string.h>
using namespace std;
//歐拉函數:
//f(n) = n*TT[ 1/p * (p-1) ]
//其中 p 是 n 的質因數
//實現:對於每一個質因數,除p乘p-1
int euler(int n)
{
int p;
int m = sqrt(n + 0.5); //m用來界定質因子的範圍
int ans = n;
for (p = 2; p <= m; p++)
{
if (n%p == 0)
{
ans = ans / p * (p - 1);
while (n%p == 0) n /= p; //源於唯一分解定理,排除非素
}
}
if (n != 1) ans = ans / n*(n - 1); //如果本身也是素數,就要除一下
return ans;
}
//篩選法求歐拉函數 O(nloglogn)
int table[10000];
void euler_table(int n)
{
int i, j;
for (i = 1; i <= n; i++)
table[i] = i;
for (i = 2; i <= n; i++)
{
if (table[i] == i)
{
for (j = i; j <= n; j += i)
{
table[j] = table[j]/i*(i - 1);
}
}
}
}
int main()
{
int n;
euler_table(100);
L: scanf("%d", &n);
printf("%d ", table[n]);
n = euler(n);
printf("%d\n", n);
goto L;
}
//歐拉函數的推導:
//歐拉函數 f(n) = 小於n的與n互素的數的個數(注意不是素因數)
//“積性函數” F(X*Y),當且僅當 GCD(X,Y)= 1 時, F(X*Y) = F(X)* F(Y)
//歐拉函數是積性函數(我也不知道爲什麼)
//所以 根據唯一分解定理 n = p1^a1 * p2^a2 * ... * pn^an
//f(n) = p(p1^a1) * p(p2^a2) * ... * p(pn^an)
//對於p1^a1 其中因數的個數爲 p1^a1 - p1^a1/p1 == p1^a1 * (1 - 1/p1)
//f(n) = p1^a1*p2^a2... ... *(1 - 1/p1)*(1 - 1/p2)*... ...
// = n * TT(1 - 1/pi) = n * TT[1/pi*(pi-1)]
[數論]小於n且與n互素的個數(歐拉函數)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.