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
Input begins with an integer t ≤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
首先如果出现f[i]=f[1]&&f[i-1]=f[0]则出现循环,
而对n的模数只有n种可能,故n^2内便出现循环。
故,先求出循环节M,
再求a^b%M,快速幂即可。
#include <iostream>
#include <cstdio>
#include <map>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include<cassert>
using namespace std;
#define LL unsigned long long
#define maxn 1010
int f[maxn*maxn];
int quickpow(LL m,LL n,int k)
{
int b=1;
while(n>0)
{
if(n&1){
b=(b*m)%k;
}
n=n>>1;
m=(m*m)%k;
}
return b;
}
int main() {
int n,t,m,M;
LL a,b;
scanf("%d",&t);
while(t--){
scanf("%llu%llu%d",&a,&b,&n);
if(n==1||a==0){
printf("0\n");
}
else{
f[0]=0;
f[1]=1;
m=n*n+10;
for(int i=2;i<=m;i++){
f[i]=(f[i-1]+f[i-2])%n;
if(f[i]==f[1]&&f[i-1]==f[0]){
M=i-1;
break;
}
}
int k=quickpow(a%M,b,M);
printf("%d\n",f[k]);
}
}
return 0;
}