问题描述:
这题花了我一天时间调,还是自己渣,很多细节都没注意。
分析:
因为要求的是
f(ab)
mod
n
,那么就可以设
这里有一个关键的地方,
f(i)
mod
n
会重复循环,为什么会这样呢?因为斐波那契数列的每一项都只和前两项有关。所以共有
这下就可以先建一个 F(i) 的表:因为根据斐波那契数列递推式:
- f(i)=f(i−1)+f(i−2) //式1
根据式1和 (a+b) mod n=(a mod n+b mod n) mod n 得出
f(i) mod n=(f(i−1) mod n+f(i−2) mod n) mod n //式2而
F(i)=f(i) mod n //式3则根据式2和式3得出
F(i)=(f(i−1) mod n+f(i−2) mod n) mod n=(F(i−1)+F(i−2)) mod n
即
最后找到
ab
的位置,查表即可。
代码如下:
void Fibonacci_F()
{
F[0] = 0;
F[1] = 1;
for(int i=2; ; i++)
{
F[i] = (F[i-1] + F[i-2]) % n;
if(F[i-1] == 0 && F[i] == 1)
{
k = i-1;
break;
}
}
return;
}
完整代码如下:
#include<cstdio>
#include<iostream>
using namespace std;
typedef unsigned long long LL;
const int maxn = 10000000+10;
int F[maxn];
LL a,b;
int n,k;
/*建表*/
void Fibonacci_F()
{
F[0] = 0;
F[1] = 1;
for(int i=2; ; i++)
{
F[i] = (F[i-1] + F[i-2]) % n;
if(F[i-1] == 0 && F[i] == 1)
{
k = i-1;
break;
}
}
return;
}
/*幂求模*/
int pow_mod(LL a, LL b, int n)
{
if(b == 0) return 1;
int x = pow_mod(a, b/2, n);
x = x * x % n;
if(b%2 == 1) x = x * a % n;
return x;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>a>>b>>n;
if(a == 0 || n == 1)
{
cout<<0<<endl;//关键。
}
else{
Fibonacci();
printf("%d\n",F[pow_mod(a%k,b,k)]);
}
}
return 0;
}
有一个细节很重要:
if(a == 0 || n == 1)
{
cout<<0<<endl;//关键。
}
就是因为少了这个,我一直runtime error,所以细节决定成败。