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; }