題目鏈接:http://www.bnuoj.com/v3/problem_show.php?pid=20000
The i'th Fibonacci number f (i) is recursively defined in the following way:
- f (0) = 0 and f (1) = 1
- f (i+2) = f (i+1) + f (i) for every i ≥ 0
Your task is to compute some values of this sequence.
Input begins with an integer t ≤ 10,000, the number of test cases. Each test case consists of three integers a,b,nwhere 0 ≤ a,b < 264 (a and b will not both be zero) and 1 ≤ n ≤ 1000.
For each test case, output a single line containing the remainder of f (ab) upon division by n.
Sample input
3 1 1 2 2 3 1000 18446744073709551615 18446744073709551615 1000
Sample output
1 21 250
/*
給定a,b,n,求fib[(a^b)%n]
a,b的範圍到unsigned long long,f(a^b)還要再mod上n
n的範圍才1000,f(x)的遞推式又有了,很容易就想到週期這東西。cycle求循環節。比如n=3,前10項:1,1,2,0,2,2,1,0,1,1。發現第9.10項和0.1項一樣就是從9又循環一遍
那麼對a^b用快速冪
*/
#include<iostream>
using namespace std;
typedef unsigned long long LL;
const int MAX=10000+10;
LL fib[MAX];
int cycle(int n)//求循環節
{
fib[0]=0;fib[1]=1%n;fib[2]=(fib[0]+fib[1])%n;
for(int i=3;i<MAX;++i){
fib[i]=(fib[i-1]+fib[i-2])%n;
if(fib[i-1]==fib[0]&&fib[i]==fib[1]) return i-1; //連續兩項與開頭兩項相同即可認定循環
}
return 1;
}
LL pow_mod(LL a,LL b,LL m) //快速冪
{
if(b==0) return 1;
LL x=pow_mod(a,b/2,m);
LL ans=x*x%m;
if(b%2==1) ans=ans*a%m;
return ans;
}
int main()
{
LL a,b,n,T;
cin>>T;
while(T--)
{
cin>>a>>b>>n;
int t=cycle(n); //t爲循環長度
LL ab=pow_mod(a%t,b,t); //快速冪
cout<<fib[ab]<<endl; //結果
}
return 0;
}