1. 程式人生 > 實用技巧 >Colossal Fibonacci Numbers! UVA - 11582

Colossal Fibonacci Numbers! UVA - 11582

題目連結:UVA - 11582

本題的關鍵就是對於斐波那契數列,如果f(n)和f(n + 1)與之前某個f(i)和f(i + 1)一樣,則f(n + 2)也會和f(i + 2)一樣,於是乎接下來的都一樣了,由於f(n)對mod求模,則每個f的值都在0~mod之間,最多組合有mod*mod種,也就是說可以在規定時間內知道迴圈的,而且斐波那契數列的迴圈節是純迴圈的,所以我們為了簡便,就取f(1),f(2)為基準,也就是出現了f(i),f(i+1)均為1的時候,就結束。此時迴圈節大小為i - 2,我們把m設為i - 2,我們最後通過求f(ab)對於mod的模實際上就是求f(ab%m)對mod的模。注意當a = 0或者mod = 0時要特判。

AC程式碼:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
int mod, m;
ll f[1000005];
int power(ll a, ll b) {//求a^b對於m求模的快速冪,ab%m == ((a % m) * (b % m)) % m
    if(b == 0)
        return 1;
    int temp = power(a, b / 2);
    temp = (ll)temp * temp % m;
    if(b & 1)
        
return temp * a % m; else return temp; } int main() { int t; ll a, b; scanf("%d", &t); f[1] = f[2] = 1; for(int cnt = 0; cnt < t; cnt++) { scanf("%llu %llu %d", &a, &b, &mod); if(mod == 1 || a == 0)//特判 { printf(
"0\n"); continue; } for(int i = 3; i <= 1000000; i++)//找到迴圈節 { f[i] = (f[i - 1] + f[i - 2]) % mod; if(f[i] == 1 && f[i] == f[i - 1])//如果出現了f[i]和f[i + 1]都是1,則出現迴圈了,迴圈節就是從1到達i-2,長度為i-2 { m = i - 2;//迴圈節長度 break; } } printf("%llu\n", f[power(a % m , b)]); } return 0; }