题解
首先在%n意义下,斐波那契是会有循环节的,这个循环节是多少呢?因为只要有任意两个一样,那么后面一直累加出来的数列也是一样的,那就会出现一个循环节。有n^2个不同的两个的组合,所以n^2项左右一定会出现循环节,实测n=1000的话循环节在1501,比想象的小很多。找到循环节了就可以%了,k=a^b%M(循环节长度)用快速幂取余。算出来后直接输出f[k]就行了。
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef unsigned long long ll;
using namespace std;
const int maxn=1000+10;
ll a,b;
int f[maxn*maxn],n,M;
//快速幂 求a^p % Mod
int pow(ll a,ll p,int Mod)
{
int ret=1;
while(p)
{
if(p & 1)ret*=a,ret%=Mod;
a*=a;a%=Mod;
p>>=1;
}
return ret;
}
inline void solve()
{
cin>>a>>b>>n;
if(n==1||!a){printf("0\n");return ;}
f[1]=1,f[2]=1;
for(int i=3;i<=n*n+10;i++)
{
f[i]=f[i-1]+f[i-2];f[i]%=n;
if(f[i]==f[2]&&f[i-1]==f[1]) {M=i-2;break;}
}
int k=pow(a%M,b,M);
printf("%d\n",f[k]);
}
int main()
{
int T;cin>>T;
while(T--) solve();
return 0;
}