思路是按紫书上说的来。
参考了:https://blog.csdn.net/qwsin/article/details/51834161 的代码;
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 using namespace std; 5 typedef unsigned long long ll; 6 const int MAXN=1005+5; 7 8 ll a, b; 9 int n,M; 10 int f[MAXN*MAXN]; 11 12 int pow_mod(ll p, ll q, int Mod) 13 { 14 if(!q) return 1; 15 int x = pow_mod(p, q/2, Mod); 16 int ans = x*x % Mod; 17 if(q%2) 18 ans = ans*p % Mod; 19 return ans; 20 } 21 22 void solve() 23 { 24 cin>>a>>b>>n; 25 if(n==1 || a==0) 26 { 27 printf("0\n"); 28 return ; 29 } 30 f[0]=0; f[1]=1; 31 int t=n*n; 32 for(int i=2; i<=t+100; i++) 33 { 34 f[i]=(f[i-1]+f[i-2])%n; 35 if(f[i]==f[1] && f[i-1]==f[0]) 36 { 37 M=i-1; 38 break; 39 } 40 } 41 int k = pow_mod(a%M, b, M); 42 cout<<f[k]<<endl; 43 44 } 45 46 47 48 int main() 49 { 50 int T; 51 cin>>T; 52 while(T--) 53 solve(); 54 55 return 0; 56 }
代码中的ll改成ull比较合适。
注意第30行的初始值,我因为f[0]=1 卡了好几个小时。
另一种是LRJ的代码,为了方便大家看,我直接copy过来了。
1 // UVa11582 Colossal Fibonacci Numbers! 2 // Rujia Liu 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 8 const int maxn = 1000 + 5; 9 typedef unsigned long long ULL; 10 11 int f[maxn][maxn*6], period[maxn]; 12 13 int pow_mod(ULL a, ULL b, int n) { 14 if(!b) return 1; 15 int k = pow_mod(a, b/2, n); 16 k = k * k % n; 17 if(b % 2) k = k * a % n; 18 return k; 19 } 20 21 int solve(ULL a, ULL b, int n) { 22 if(a == 0 || n == 1) return 0; // attention! 23 int p = pow_mod(a % period[n], b, period[n]); 24 return f[n][p]; 25 } 26 27 int main() { 28 for(int n = 2; n <= 1000; n++) { 29 f[n][0] = 0; f[n][1] = 1; 30 for(int i = 2; ; i++) { 31 f[n][i] = (f[n][i-1] + f[n][i-2]) % n; 32 if(f[n][i-1] == 0 && f[n][i] == 1) { 33 period[n] = i - 1; 34 break; 35 } 36 } 37 } 38 ULL a, b; 39 int n, T; 40 cin >> T; 41 while(T--) { 42 cin >> a >> b >> n; 43 cout << solve(a, b, n) << "\n"; 44 } 45 return 0; 46 }
其实大体上差不多,不过LRJ的关键代码是用二维数组,全部先列举出来。