題目:F₁ = F₂ = 1,Fₙ = Fₙ₋₁ + Fₙ₋₂ (n ≥ 3)。輸入 n (1 ≤ n ≤ 1,000,000),輸出 Fₙ mod 10007。
樣例:10 → 55,22 → 7704。
Fₙ 指數級增長,n=1,000,000 時位數超過 20 萬位,無法直接儲存。(a + b) mod m = (a mod m + b mod m) mod m。[0, 10006] 範圍內,完全避免大數問題。#include
#define MOD 10007
int main() {
int n;
if (scanf("%d", &n) != 1) return 1;
if (n <= 2) { printf("1\n"); return 0; }
int a = 1, b = 1, c;
for (int i = 3; i <= n; i++) {
c = (a + b) % MOD;
a = b;
b = c;
}
printf("%d\n", b);
return 0;
}
若 n 擴大至 10¹⁸,需用矩陣快速冪:
[Fₙ ] = [1 1]^(n-2) * [F₂]
[Fₙ₋₁] [1 0] [F₁]
配合模運算,同樣適用。但本題 n ≤ 1e6,線性迭代完全足夠 (約 10⁶ 次運算,< 10ms)。
| 錯誤 | 後果 | 修正 |
|---|---|---|
| 用 int 直接算 Fₙ 再取模 | 極快溢位 (n>46 即溢位 32-bit int) | 每步取模 |
陣列開太大 int F[1000001] | 棧溢位 (約 4MB 超過預設 1-8MB 棧) | 用靜態/全域陣列,或滾動變數 O(1) 空間 |
| 忘記 n=1,2 直接輸出 1 | 迴圈不執行,輸出未初始化值 | 前置判斷 |
| 模數寫錯 (1007/100007) | 答案錯誤 | 定義常數 #define MOD 10007 |
int 足夠容納模 10007 後的中間結果。此題完美展示「數學性質 + 空間優化」如何將看似需要大數運算的問題轉化為極簡高效的解法。