题目大意:
输入两个非负整数a,b和正整数n(0<= a,b<= 264 2 64 ,1<= n <= 10000),你的任务就是计算f( ab a b )除以n的余数。其中f( 0 ) = 0, f( 1 ) = 1,且对于所有非负整数 i i ,f() = f( i+1 i + 1 ) + f( i i )。
思路:起初也没什么思路,这题数量太大,这样应该先考虑是不是有规律。。。
1、由于是每一项都是对 n 取模,所以不同的 n 值都会对应一个周期,只要循环一下。当前项等于 ,前一项等于
f0
f
0
时就可以跳出循环了。
int solve(int n) {
F[0] = 0;
F[1] = 1 % n;
for (int i = 2; ; i++) {
F[i] = (F[i-1] + F[i-2]) % n;
if (F[i-1] == F[0] && F[i] == F[1])
return i - 1;
}
}
2、a的b次方法用快速幂乘法:
unsigned long long pow_m(unsigned long long a,unsigned long long b,unsigned long long n)
{
unsigned long long sum = 1;
while(b > 0)
{
if(b&1) sum *= a%n;
b >>= 1;
a = (a*a)%n;
}
return sum;
}
最后附上ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1024;
int F[N*N];
int pow_m(unsigned long long a,unsigned long long b,int n)
{
a %= n;
unsigned long long sum = 1;
while(b != 0)
{
if(b&1) sum = (sum*a)%n;
b >>= 1;
a = (a*a)%n;
}
return sum;
}
int solve(int n) {
F[0] = 0;
F[1] = 1 % n;
for (int i = 2; ; i++) {
F[i] = (F[i-1] + F[i-2]) % n;
if (F[i-1] == F[0] && F[i] == F[1])
return i - 1;
}
}
int main()
{
int t;
unsigned long long a,b,s;
int n;
scanf("%d",&t);
while(t--)
{
scanf("%llu%llu%d",&a,&b,&n);
if(a == 0||n == 1) cout<< 0 <<endl;
else{
int p = pow_m(a, b, solve(n));
//cout<<p<<endl;
cout << F[p] << endl;
}
}
return 0;
}