A Colossal Fibonacci Numbers! (循环节)
题意:求fibonacci数列f(a^b)项mod n (0<a,b<$2^64$,$1<=n<=1000$)
题解:
我见过的fibonacci数列的常见处理方式:
1. 递推;
2. 矩阵快速幂:$$\begin{pmatrix} f(n) & f(n-1) \\ 0 & 0 \\ \end{pmatrix} * \begin{pmatrix} 1 & 1 \\ 1 & 0 \\ \end{pmatrix} = \begin{pmatrix} f(n)+f(n-1) & f(n) \\ 0 & 0 \\ \end{pmatrix} $$(这个东西老是忘记) ,定义一个矩阵类,再用快速幂运算,O(2^3*logn),ll内肯定是可以处理的,更高的连指数都要高精了;
3.fibonacci的通项:
记方程$x^2 - x - 1 = 0 $的两个根为:$$\phi = \frac{1+\sqrt{5}}{2} \ \ \hat{\phi} = \frac{1-\sqrt{5}}{2}$$ fibonacci的通项为 $$f(i) = \frac{\phi^i - \hat{\phi}^i}{\sqrt{5}}$$
证明:1.代入验证f(0)=0;f(1)=1;
2.注意到对于两个根:$$x + 1 = x^2$$ 所以:$$f(n-1)+f(n-2)\\= \frac{\phi^{i-1} - \hat{\phi}^{i-1}}{\sqrt{5}} + \frac{\phi^{i-2} - \hat{\phi}^{i-2}}{\sqrt{5}}\\=\frac{\phi^{i-1} + \phi^{i-2}}{\sqrt{5}} - \frac{\hat{\phi}^{i-1} + \hat{\phi}^{i-2}}{\sqrt{5}}\\=\frac{\phi^{i-2}(\phi+1)}{\sqrt{5}} - \frac{\hat{\phi}^{i-2}(\hat{\phi}+1)}{\sqrt{5}}\\= \frac{\phi^{i-2} \phi^2}{\sqrt{5}} - \frac{\hat{\phi}^{i-2} \hat{\phi}^{2}}{\sqrt{5}}\\= \frac{\phi^i - \hat{\phi}^i}{\sqrt{5}}\\=f(n)\\$$
同时因为$$0 \lt |\hat{\phi}| \lt 1\\0 \lt |\hat{\phi}^i| \lt 1\\\frac{| \hat{\phi}^{i}|}{\sqrt{5}} \lt \frac{1}{2}$$,所以f(i)就是$\frac{\phi^i}{sqrt{5}}$四舍五入到的整数,所以f(i)成指数增长;
可以用来证明欧几里得算法的复杂度(考虑(fi+1,fi));
4.循环节:递推公式f(n)=f(n-1)+f(n-2),所以如果有二元组(f(i),f(i-1))重复出现的话就有循环节,而在mod n 的意义下最多有n^2个不同的二元组,那么直接枚举判断就好了;
更好的求循环节(挖坑):https://blog.csdn.net/acdreamers/article/details/10983813
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<cmath> 7 #include<vector> 8 #include<stack> 9 #define Run(i,l,r) for(int i=l;i<=r;i++) 10 #define Don(i,l,r) for(int i=l;i>=r;i--) 11 #define ll unsigned long long 12 #define inf 0x3f3f3f3f 13 using namespace std; 14 const int N=1000010; 15 ll f[N]; 16 ll pw(ll x,ll y,ll mod){ 17 x %= mod; 18 ll res = 1; 19 for(ll i=y;i;i>>=1){ 20 if(i&1)res = res * x %mod; 21 x = x * x %mod; 22 } 23 return res; 24 } 25 int main(){ 26 //freopen("A.in","r",stdin); 27 //freopen("A.out","w",stdout); 28 int T;cin >> T; 29 ll a,b,n; 30 while(T--){ 31 cin >> a >> b >> n; 32 int i,mx=n*n+1; 33 f[0]=0;f[1]=1%n; 34 for(i=2;i<=mx;i++){ 35 f[i] = (f[i-1] + f[i-2])%n; 36 if(f[i]==f[1]&&f[i-1]==f[0]){ 37 i--; 38 break; 39 } 40 } 41 cout << f[pw(a,b,i)] << endl; 42 } 43 return 0; 44 }//by tkys_Austin;