斐波那契數列第N項f(N)[矩陣快速冪]
阿新 • • 發佈:2017-10-06
string sin int code char const mat ret truct
矩陣快速冪
定義矩陣A(m*n),B(p*q),A*B有意義當且僅當n=p。即A的列數等於B的行數。
且C=A*B,C(m*q)。
例如:
進入正題,由於現在全國卷高考不考矩陣,也沒多大了解。因為遇到了斐波那契這題...
註意到: Fn+1=Fn+Fn-1
我們會有:
則:
所以我們只需要想辦法求矩陣A的冪,這時候我們當然想要用快速冪。
代碼部分:
定義矩陣:
struct matrix{ ll a[3][3]; };
(類比整數的快速冪)預處理:
[我們需要一類似於1的矩陣:]
『1 0 0
0 1 0
0 0 1』類似這種操作...
void init(){ int i,j; memset(res.a,0,sizeof res.a); for(i=1;i<=2;i++) res.a[i][i]=1; base.a[1][1]=1; base.a[1][2]=1; base.a[2][1]=1; base.a[2][2]=0;
}
矩陣乘法:[就該題而言]
matrix mul(matrix p,matrix q){ int i,j,k; matrix m; memset(m.a,0,sizeof m.a); for(i=1;i<=2;i++) for(j=1;j<=2;j++) for(k=1;k<=2;k++) m.a[i][j]=(m.a[i][j]+p.a[i][k]*q.a[k][j])%Mod; return m; }
快速冪:
void mfpow(ll p){ init(); while(p){ if(p&1) res=mul(base,res); base=mul(base,base); p>>=1; } }
全部的代碼:(lowbee的難免會差一些,請大佬們見諒...)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll ; 6 inline ll read(); 7 const ll Mod = 1e9 + 7 ; 8 struct matrix{ 9 ll a[3][3]; 10 }; 11 matrix res,base; 12 ll ans; 13 ll c[3]; 14 ll n; 15 namespace lys{ 16 void init(){ 17 int i,j; 18 memset(res.a,0,sizeof res.a); 19 for(i=1;i<=2;i++) res.a[i][i]=1; 20 base.a[1][1]=1; 21 base.a[1][2]=1; 22 base.a[2][1]=1; 23 base.a[2][2]=0; 24 } 25 matrix mul(matrix p,matrix q){ 26 int i,j,k; 27 matrix m; 28 memset(m.a,0,sizeof m.a); 29 for(i=1;i<=2;i++) 30 for(j=1;j<=2;j++) 31 for(k=1;k<=2;k++) 32 m.a[i][j]=(m.a[i][j]+p.a[i][k]*q.a[k][j])%Mod; 33 return m; 34 } 35 void mfpow(ll p){ 36 init(); 37 while(p){ 38 if(p&1) res=mul(base,res); 39 base=mul(base,base); 40 p>>=1; 41 } 42 } 43 int main(){ 44 int k; 45 n=read(); 46 mfpow(n-1); 47 c[1]=1; 48 c[2]=0; 49 for(k=1;k<=2;k++) 50 ans=(ans+res.a[1][k]*c[k])%Mod; 51 cout<<ans<<endl; 52 return 0; 53 } 54 } 55 int main(){ 56 lys::main(); 57 return 0; 58 } 59 inline ll read(){ 60 ll k=0,f=1; 61 char c=getchar(); 62 while(c<‘0‘||c>‘9‘){ 63 if(c==‘-‘) 64 f=-1; 65 c=getchar(); 66 } 67 while(c>=‘0‘&&c<=‘9‘){ 68 k=k*10+c-‘0‘; 69 c=getchar(); 70 } 71 return k*f; 72 }
題目鏈接[luogu]:
https://www.luogu.org/problem/show?pid=1962
斐波那契數列第N項f(N)[矩陣快速冪]