首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

POJ 2407 Relatives:歐拉函數單次計算 O(√n) 算法

     編輯:關於C++

問題描述

給定 n (≤ 10⁹),求 1~n 中與 n 互質的正整數個數。即計算 φ(n)。多測試用例,n=0 結束。

歐拉函數公式

若 n = p₁^a₁ · p₂^a₂ · ... · pₖ^aₖ,則:

φ(n) = n · Π (1 - 1/pᵢ) = Π pᵢ^(aᵢ-1) · (pᵢ - 1)

O(√n) 分解算法

#include 
#include 

int phi(int n) {
    int res = n;
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            res = res / i * (i - 1);
            while (n % i == 0) n /= i;
        }
    }
    if (n > 1) res = res / n * (n - 1);  // 剩餘質因子
    return res;
}

int main() {
    int n;
    while (scanf("%d", &n) == 1 && n) {
        printf("%d\n", phi(n));
    }
    return 0;
}

關鍵點

  1. 試除法分解:i 從 2 到 √n,n 不斷縮小,實際極快
  2. 整除序列:`res = res / i * (i-1)` 避免浮點誤差,保證整數運算
  3. 剩餘質因子:循環結束後 n>1 則 n 本身是質數
  4. n=1 特判:φ(1)=1,代碼自然處理(循環不進入,n=1 不進 if)

複雜度