题意:已知斐波那契数列fib[0]=0;fib[1]=1;fib[i]=fib[i-1]+fib[i-2];给你数a,b,n求fib(a^b)%n是多少,范围0<=a,b<2^64,1<=n<1000
思路:斐波那契数列对n取余之类的题,存在循环节,由于a^b的数太大,我们可以通过找循环节的方式来求得fib(a^b)是哪一项,
如何求循环节呢?因为余数最多有n种,所以最多有n^2项就会出现重复,我们计算出fib(0)~fib(n^2)的值,当遇到fib(i-1)=0&&fib(i)=1时,说明找到循环节 p
如何计算(a^b)%p呢? a ^ b % p = ((a % p)^b) % p 运用快速幂
代码:
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #define ll unsigned long long using namespace std; ll qmod(ll a,ll b,ll mod) { ll ans=1; a=a%mod; while(b) { if(b&1) { ans=(ans*a)%mod; } b=b/2; a=(a*a)%mod; } return ans; } int main() { int t; cin>>t; while(t--) { ll a,b,n,cnt; cin>>a>>b>>n; cnt=0; vector <ll> fib; fib.push_back(0); fib.push_back(1); for(int i=2;i<=n*n;i++) { fib.push_back((fib[i-1]+fib[i-2])%n); cnt++; if(fib[i]==1&&fib[i-1]==0) { break; } } if(n!=1) cout<<fib[qmod(a,b,cnt)]<<endl; else { cout<<"0"<<endl; } } return 0; }