HDU 1005 定義遞歸數列 f(1)=1, f(2)=1, f(n)=(A·f(n-1)+B·f(n-2)) mod 7。給定 A、B、n (n≤10⁸),求 f(n)。直接遞歸/迭代會超時,本文揭示**模 7 下狀態只有 49 種**,必存在循環節,利用週期性將 n 取模化為小數值求解。
#include <stdio.h>
int f[10000]; // 足夠大捕捉循環節
int main() {
int A, B, n;
while (scanf("%d %d %d", &A, &B, &n) == 3) {
if (A == 0 && B == 0 && n == 0) break;
f[1] = 1;
f[2] = 1;
int period = 0;
// 1. 尋找循環節
for (int i = 3; i < 10000; i++) {
f[i] = (A * f[i-1] + B * f[i-2]) % 7;
if (f[i] == 1 && f[i-1] == 1) {
period = i - 2; // 循環節長度
break;
}
}
// 2. 映射 n 到循環節內
// 注意:f[1]..f[period] 為一個完整週期
// f[period+1]=1, f[period+2]=1 開始下一輪
n = n % period;
if (n == 0) n = period; // n 是 period 的倍數時,對應週期最後一項
printf("%d\n", f[n]);
}
return 0;
}
輸入:
1 1 3
1 2 10
0 0 0
輸出:
2
5
驗證:A=1,B=1 為標準費波那契模 7,序列:1,1,2,3,5,1,6,0,6,6,5,4,2,6,1,0,1,1... 週期 16。f(3)=2 ✓
HDU 1005 是**模算術週期性**思想的經典入門題。關鍵在於識別「狀態空間有限 → 必存在循環」,將大數 n 映射到小週期內。此技巧廣泛應用於線性遞歸數列模運算、矩陣快速冪取模、博弈論 SG 函數週期性等進階問題。