Colossal Fibonacci Numbers!
Time Limit: 1000MS Memory Limit: Unknown
Description:
The i’th Fibonacci numberf(i) is
recursively defined in the following
way:
• f (0) = 0 and f (1) = 1
• f ( i + 2 ) = f(i + 1) + f( i )
for
everyi ≥ 0 .
Your task is to compute some
values of this sequence.
Input:
Input begins with an integert ≤
10, 000, the number of test cases.
Each test case consists of three integers
a,b,n where 0 ≤ a, b < 2^
64
(a and b will not both be zero) and
1 ≤ n ≤ 1000.
Output:
For each test case, output a single line containing the remainder of f(a^
b) upon division by
n.
Sample Input:
3
1 1 2
2 3 1000
18446744073709551615 18446744073709551615 1000
Sample Output:
1
21
250
算法分析:
所有的计算都是对n取模,设F (i) =f (i) modn,很容易发现,当二元组(F (i - 1),F (i )) 重复的时候,整个序列也就重复。
例,n = 3,序列 F( i ) 的前 10 项为1,1,2,0,2,2,1,0,1,1,第 9、10 项和前两项完全一样。根据递推公式,第11项会等于第3项,第12项等于第4项……,从而找出规律以及循环节长度!
代码实现:
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
const int Max = 10010;
int f[Max];
ull a, b;
int solve(int n)///找出余数为n时的循环节长度
{
f[0] = 0;
f[1] = 1 % n;///开始没对f[1]做模运算,无数次Runtime Error
for(int i = 2; i ; i++)
{
f[i] = (f[i - 1] % n + f[i -2] % n) % n;
if(f[i] == f[0] && (f[i] + f[i-1]) % n == f[1])
return i;
}
return 1;
}
int pow(int a, ull b, int m)///幂取模运算(a^b)%m(采用分治法降低时间复杂度)
{
int mid, ans;
if(b == 0)
return 1%m;
mid = pow(a,b/2,m);
ans = mid * mid % m;
if(b&1)
ans = ans * a % m;
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int n, mod, ans;
cin >> a >> b >> n;
mod = solve(n);
ans = pow(a%mod,b,mod);
printf("%d\n",f[ans%mod]);
}
return 0;
}