题目链接 https://cn.vjudge.net/problem/UVA-11582
【题意】
输入两个非负整数a,b和正整数n(0<=a,b<=2^64, 1<=n<=1000),你的任务是计算f(a^b)除以n的余数,其中f(0)=0,f(1)=1,当i>=0时,f(i+2)=f(i+1)+f(i)
【思路】
所有计算都会对n取模,并且n的范围很小,设F(i)=f(i) mod n. 那么当F(i),F(i+1)和F(0),F(1)重复时,整个序列就开始重复,根据这个性质找出循环节即可.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
typedef unsigned long long ull;
ull pw(ull x,ull n,ull mod){
ull ans=1;
while(n){
if(n&1) ans=(ans*x)%mod;
x=(x*x)%mod;
n/=2;
}
return ans;
}
vector<ull> f;
int main(){
int T;
cin>>T;
while(T--){
f.clear();
ull a,b,n;
cin>>a>>b>>n;
if(1ULL==n){ cout<<"0\n";continue; }
f.push_back(0ULL);
f.push_back(1ULL);
ull cnt=0ULL;
for(int i=2;;++i){
f.push_back((f[i-1]+f[i-2])%n);
++cnt;
if(f[i-1]==f[0] && f[i]==f[1]) break;
}
ull ans=f[pw(a%cnt,b,cnt)];
cout<<ans<<endl;
}
return 0;
}