分析: 所有计算都是对n取模。不妨设F(n) = f(i) mod n. 不难发现,当二元组(F(i),F(i+1))出现重复是,整个序列都开始重复。例如,n=3,序列F(i)的前10项1,1,2,0,2,2,1,0,1,1,第九项和第十项与前两项完全一样。
因为余数最多n种,所以最多n^2项就会出现重复。设周期为M,只需计算出F(0)~F(n^2),然后算出F(a^b)等于其中哪一项即可。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef unsigned long long ll;
const int maxn = 1e3+10;
int f[maxn*maxn],n,cir;
ll a,b;
void init(){
f[0] = 0; f[1] = 1; f[2] = 1;
for (int i=3; i<=n*n+20; i++) {
f[i] = (f[i-1]+f[i-2])%n;
if (f[i]==f[2] && f[i-1]==f[1]) {cir = i-2; break;}
}
}
int pow(ll a, ll b, int cir){
int ans = 1;
while (b){
if (b&1) {ans *= a; ans %= cir;}
a = (a*a)%cir;
b >>=1;
}
return ans;
}
int main(){
int t;
cin>>t;
while (t--){
cin >> a >> b >> n;
if (n==1 || !a) {printf("0\n"); continue;}
init();
int x=pow(a%cir,b,cir);
printf("%d\n",f[x]);
}
return 0;
}