链接:https://www.nowcoder.com/acm/contest/93/K
来源:牛客网
题目描述
wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n>=2)
一天他突发奇想,想求F(a^b)%c
输入描述:
输入第一行一个整数T(1<=T<=100),代表测试组数
接下来T行,每行三个数 a,b,c (a,b< =2^64) (1 < c<1000)
输出描述:
输出第a^b项斐波那契数对c取余的结果
示例1
输入
3
1 1 2
2 3 1000
32122142412412142 124124124412124 123
输出
1
21
3
解题思路 :
观察到 c很小 根据经验可知 可找循环节。
不过要注意的是 a b 有2的64次方 longlong存不下 要开ull
史诗级巨坑。。。。。。。。。。 气死我了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<queue>
#include<cmath>
#define ull unsigned long long
using namespace std;
ull loop[3000];
ull qickpow(ull a,ull b,ull MOD){
ull ans=1;
a%=MOD,b%=MOD;
while(b){
if(b&1) ans=(ans%MOD*a%MOD)%MOD;
b>>=1;
a=(a%MOD*a%MOD)%MOD;
}
return ans;
}
ull F(int len,ull MOD){
if(len==0) return 0;
ull f1=0,f2=1;
for(int i=2;i<=len;i++){
ull cnt=(f1%MOD+f2%MOD)%MOD;
f1=f2;
f2=cnt;
}
return f2;
}
int main() {
for(int i=2;i<=1000;i++){
ull f1=1,f2=1;
for(int j=0;j<1000000;j++){
if(f1==1 && f2==1 && j){
loop[i]=j;
//cout<<j<<endl;
break;
}
ull cnt=(f2+f1)%i;
f1=f2;
f2=cnt;
}
}
int T;
cin>>T;
while(T--){
ull a,b,c;
cin>>a>>b>>c;
//cout<<loop[c]<<endl;
ull cnt=qickpow(a,b,loop[c]);
cout<<F(cnt,c)%c<<endl;
}
return 0;
}