算術基本定理,又稱為正整數的唯一分解定理,即:每個大於1的自然數均可寫為質數的積,而且這些素因子按大小排列之後,寫法僅有一種方式。例如:
簡而言之,唯一分解定理就是說任意乙個大於1的自然數都可以寫為幾個素數的冪的乘積。記住這個就足夠了(不困難嘛)。
在簡單的了解了唯一分解定理後,思考乙個問題,如何求小於等於n的自然數中與n互質的數的數量(好繞口),簡單說就是,在[1,n]區間中與n互質的數有多少個(這下好多了),尤拉函式就是這個東西了,
表示在[1,n]區間中與n互質的數的數量。既然我們前面講了唯一分解定理,那麼通過直覺可以證明(無視這句)尤拉函式與唯一分解定理有關。我們來考慮乙個例子,對於整數n=360,將其分解得到
可知2,3,5都是360的素因子。在[1,360]這個區間中,2,3,5都是360的素因子,必然是360的約數,所以2的倍數,3的倍數,5的倍數都是360的約數,[1,360]中2的倍數有360/2個,3的倍數有360/3個,5的倍數有360/5,這些數都不可能與360互質,所以有
=360-360/2-360/3-360/5。看上去是對的,但是很遺憾,360-360/2-360/3-360/5=-12,是乙個明顯不正確的負數,為什麼會這樣呢,我們考慮這樣的幾個數:6,10,15,6在作為2的倍數時已經減過一次了,但是作為3的倍數的時候又被減了一次,多減了一次,10也同樣,作為2,5的倍數被減了兩次,像這樣的數一共有360/(2*3)+360/(2*5)+360/(3*5)個,為了體現公平公正的原則(無視這句),我們要將多減的這一次加回來,所以
=360-360/2-360/3-360/5 + 360/(2*3)+360/(2*5)+360/(3*5) = 108,這下結果是正數了,總應該對了吧,but(最討厭但是了),來考慮一下30這個數,他在作為2,3,5的倍數的時候被減了3次,又在作為6,10,15的倍數的時候被加了三次,總結起來就是根本沒把他算上嘛!為了體現公平公正的原則(夠了!),我們要把他和他的倍數計算在內,即:
=360 -360/2-360/3-360/5 + 360/(2*3)+360/(2*5)+360/(3*5) –360/(2*3*5) = 96.終於正確了!
剛剛360只是3個質因子的冪的乘積,但是如果有更多的分解的質因子呢,當然就要反覆的如上考慮了(不過會複雜一點),其實剛剛說了這麼多,其實都是屬於乙個叫做容斥原理對於正整數的唯一分解式:
有以上就是高大上的定義,但是如此高階的東西顯得太平易近人了,雖然完全不明顯,但是這個高大上的玩意兒是可以轉化成
雖然中間的過程並不好理解,但是我們通過這乙個簡潔的式子是可以用感性的方法去理解的,對於任意乙個素因子p,我們可以選著選他或者不選他,選的話就相當於選了-1/p作為展開式其中一項的因數,不選的話就相當於用1作為其中一項的因數(即沒有影響)。
有了簡化的公式,尤拉函式的程式實現就變得非常的簡單了,注意我沒有先生成n的唯一分解,而是邊分解邊計算結果,下面是**
int euler_phi(int n)如果要求1~n所有數的尤拉函式值,就需要用到類似於篩素數的思想了,給**:if(n>1)ret=ret/n*(n-1);//n可能也是質數
return ret;
}
const int maxn=100+10;標籤: 數學,尤拉函式,唯一分int phi[maxn];//儲存結果
void phi_table(int n)
}
病毒(唯一分解定理 尤拉篩)
chen 03 會製造電腦病毒。有人把 jay 的電腦植入了病毒,而要解除病毒,jay 要回答一道題。在電腦螢幕上有乙個數n jay 被要求輸入乙個正整數,這個數能被 1,n 內所有數整除,並且要保持這個數最小,因為這個數可能很大,所以只要輸出對109 7取模的結果就行了。然而 jay 成功的破解了...
唯一分解定理
任意乙個大於1的正整數都能表示成若干個質數的乘積,且表示的方法是唯一的。換句話說,乙個數能被唯一地分解成質因數的乘積。因此這個定理又叫做唯一分解定理。c include include include using namespace std int main int num 32 int local...
唯一分解定理
唯一分解定律 又稱為正整數的唯一分解定理,即 每個大於1的自然數均可寫為質數的積,而且這些素因子按大小排列之後,寫法僅有一種方式。當題目有大數相除,求餘數時,精度要求高時.就要運用唯一分解定律 以下唯一分解定律證明 為了真正地證明,分解質因數的方法是唯一的,我們將再次用到反證法。假設存在某些數,它們...