广义Fibonacci数列找循环节
今天將來(lái)學(xué)習(xí)如何求廣義Fibonacci數(shù)列的循環(huán)節(jié)。
?
問(wèn)題:給定,滿(mǎn)足,求的循
?????環(huán)節(jié)長(zhǎng)度。
?
來(lái)源:http://acdreamoj.sinaapp.com/?1075題
?
分析:我們知道矩陣的遞推關(guān)系如下
?
????
?
?????然后繼續(xù)有
?
????
?
???? 那么,現(xiàn)在的問(wèn)題就轉(zhuǎn)化為求最小的,使得
?
?????
?
???? 所以我們可以先找出符合條件的一個(gè),然后枚舉它的因子,找最小的。設(shè)
?
?????
?
?????為了好解決問(wèn)題,我們需要對(duì)矩陣進(jìn)行相似對(duì)角化,即,我們先來(lái)求的特征值。
?
????
????
?????解得的特征值為
?
????
?
?????也就是說(shuō)的相似對(duì)角矩陣為
?
????
?
? ? ? 因?yàn)槲覀冎?#xff0c;所以當(dāng)時(shí),,?由于
??
?????
?
??????繼續(xù)得到
?
???????
?
??????設(shè),那么分情況討論:
?
?????? (1)是模的二次剩余,由費(fèi)馬小定理得時(shí),
?
???????(2)是模的二次非剩余,則有
?
???????????
?
?????????? 根據(jù)歐拉準(zhǔn)則有
?
??????????
?
?????????? 那么繼續(xù)得到
?
???????????
?
???????????然后由費(fèi)馬小定理有,同理有
?
?????????? 所以,當(dāng)時(shí),
?
?????? (3)時(shí),由于不存在,所以無(wú)法完成相似對(duì)角化,好在這種情況不存在。
????
?
??????所以綜上所述:
???
??????是模的二次剩余時(shí),枚舉的因子
????? 是模的二次非剩余時(shí),枚舉的因子
?
????? 找最小的因子,使得
?
?????
?
????? 成立。
?
代碼:
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include <math.h>using namespace std; typedef long long LL; const int N = 2; const LL MOD = 1000000007;LL fac[2][505]; int cnt,ct;LL pri[6] = {2, 3, 7, 109, 167, 500000003}; LL num[6] = {4, 2, 1, 2, 1, 1};struct Matrix {LL m[N][N]; } ;Matrix A; Matrix I = {1, 0, 0, 1};Matrix multi(Matrix a,Matrix b) {Matrix c;for(int i=0; i<N; i++){for(int j=0; j<N; j++){c.m[i][j] =0;for(int k=0; k<N; k++){c.m[i][j] += a.m[i][k] * b.m[k][j];c.m[i][j] %= MOD;}}}return c; }Matrix power(Matrix A,LL n) {Matrix ans = I, p = A;while(n){if(n & 1){ans = multi(ans,p);n--;}n >>= 1;p = multi(p,p);}return ans; }LL quick_mod(LL a,LL b) {LL ans = 1;a %= MOD;while(b){if(b & 1){ans = ans * a % MOD;b--;}b >>= 1;a = a * a % MOD;}return ans; }LL Legendre(LL a,LL p) {LL t = quick_mod(a,(p-1)>>1);if(t == 1) return 1;return -1; }void dfs(int dept,LL product = 1) {if(dept == cnt){fac[1][ct++] = product;return;}for(int i=0; i<=num[dept]; i++){dfs(dept+1,product);product *= pri[dept];} }bool OK(Matrix A,LL n) {Matrix ans = power(A,n);return ans.m[0][0] == 1 && ans.m[0][1] == 0 &&ans.m[1][0] == 0 && ans.m[1][1] == 1; }int main() {fac[0][0] = 1;fac[0][1] = 2;fac[0][2] = 500000003;fac[0][3] = 1000000006;LL a,b,c,d;while(cin>>a>>b>>c>>d){LL t = a * a + 4 * b;A.m[0][0] = a;A.m[0][1] = b;A.m[1][0] = 1;A.m[1][1] = 0;if(Legendre(t,MOD) == 1){for(int i=0; i<4; i++){if(OK(A,fac[0][i])){cout<<fac[0][i]<<endl;break;}}}else{ct = 0;cnt = 6;dfs(0,1);sort(fac[1],fac[1]+ct);for(int i=0;i<ct;i++){if(OK(A,fac[1][i])){cout<<fac[1][i]<<endl;break;}}}}return 0; }?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的广义Fibonacci数列找循环节的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 优美的Fibonacci数列与矩阵
- 下一篇: 优先队列的应用