歐拉函數
概念:歐拉函數是小於x的整數中與x互質的數的個數,一般用φ(x)表示。特殊的,φ(1)=1。
通式 :
其中爲x的所有質因數(每個質因數只有一個),x爲正整數
那麼如何理解上面的式子呢?(轉)
對於一個質因數,因爲x以內的倍數是均勻分佈的,所以x以內有的概率是的倍數
那麼有的數不是的倍數。
對於,同理,有不是的倍數,所以有的數既不是的倍數,又不是的倍數,最後就有的數與x互質,個數自然就是
舉個例子,令x = 12。
12以內有的數是2的倍數,那麼有的數不是2的倍數(1,3,,5,,7,,9,11)
這6個數又有的數是3的倍數,只剩下的數既不是2的倍數,也不是3的倍數(1,5,7,11)
這樣剩下來的,即有4個數與12互質。
實現代碼:
(1)直接求不超過n的互質的個數
int euler(int n) {
int ans = n;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1); //先進行除法防止溢出(ans = ans * (1 - 1 / p(i)))
while (n % i == 0) n /= i;
}
}
if (n ^ 1) // n != 1
ans = ans / n * (n - 1);
return ans;
}
(2)求[1,n]之間每個數的質因數的個數
const int size = 1e6;
int euler[size];
void Init() {
memset(euler, 0, sizeof(euler));
euler[1]=1;
for(int i = 2; i < size; i++)
if(!euler[i]) {
for(int j = i; j < size; j += i) {
if(!euler[j])
euler[j] = j;
euler[j] = euler[j] / i * (i - 1);//先進行除法是爲了防止中間數據的溢出
}
}
}