1. 程式人生 > >UVa 11582 - Colossal Fibonacci Numbers!(數論)

UVa 11582 - Colossal Fibonacci Numbers!(數論)

targe ros family tdi 計算 com fibonacci numbers def

鏈接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2629

題意:

輸入兩個非負整數a、b和正整數n(0≤a,b<2^64,1≤n≤1000),你的任務是計算f(a^b)除以n的余數。
其中f(0)=0,f(1)=1,且對於所有非負整數i,f(i+2)=f(i+1)+f(i)。

分析:

所有計算都是對n取模的,設F(i)=f(i)%n。不難發現,當二元組(F(i), F(i+1))出現重復時,整個序列就開始重復。
多久會出現重復呢?因為余數最多n種,所以最多n*n項就會出現重復。實際測試出最多3001項左右就會出現重復。


所以只需計算出周期,然後算出F(a^b)對應於其中的哪一項即可。

代碼:

 1 #include <cstdio>
 2 
 3 typedef unsigned long long ULL;
 4 const int UP = 1000 + 5;
 5 int f[UP][UP*3], period[UP];
 6 
 7 int qmod(ULL a, ULL b, ULL n) { // 快速冪模
 8     a %= n;
 9     ULL res = 1;
10     while(b) {
11         if(b & 1) res = res * a % n;
12 b >>= 1; 13 a = a * a % n; 14 } 15 return res; 16 } 17 18 int main() { 19 period[1] = 1; 20 for(int n = 2; n <= 1000; n++) { 21 f[n][0] = 0; f[n][1] = 1; 22 for(int i = 2; ; i++) { 23 f[n][i] = (f[n][i-1] + f[n][i-2]) % n; 24 if
(f[n][i-1] == 0 && f[n][i] == 1) { 25 period[n] = i - 1; 26 break; 27 } 28 } 29 } 30 31 int T, n; 32 ULL a, b; 33 scanf("%d", &T); 34 while(T--) { 35 scanf("%llu%llu%d", &a, &b, &n); 36 int p = qmod(a, b, period[n]); 37 printf("%d\n", f[n][p]); 38 } 39 return 0; 40 }

UVa 11582 - Colossal Fibonacci Numbers!(數論)