浅谈矩阵加速——以时间复杂度为O(log n)的算法实现裴波那契数列第n项及前n之和使用矩阵加速法的优化求法
生活随笔
收集整理的這篇文章主要介紹了
浅谈矩阵加速——以时间复杂度为O(log n)的算法实现裴波那契数列第n项及前n之和使用矩阵加速法的优化求法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
首先請連矩陣乘法乘法都還沒有了解的同學(xué)簡單看一下這篇博客:
https://blog.csdn.net/weixin_44049566/article/details/88945949
首先直接暴力求使用O(n)的時間復(fù)雜度肯定是不行的,所以我們應(yīng)該使用更優(yōu)的時間復(fù)雜度。
?
設(shè)f(n)為裴波那契數(shù)列第n項(xiàng)。讓我們來構(gòu)造兩個矩陣:
和.
現(xiàn)在我們不妨將兩個矩陣相乘,化簡過后可以得到:,也就是.
如果再將得到的新矩陣乘以,便可以得到。
也就是我們想得到第n項(xiàng),就可以這么實(shí)現(xiàn):,也就是。
看到冪我們就可以想到快速冪,所以最后程序的時間復(fù)雜度便是O(log n)。
代碼
#include <cstdio> #include <cstring> #include <iostream> using namespace std;#define N 10 #define LL long longint n,mod;struct Matrix {LL n,m,c[N][N];Matrix() { memset(c,0,sizeof(c)); };void _read() {for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%lld",&c[i][j]);}Matrix operator * (const Matrix& a) {Matrix r;r.n=n;r.m=a.m;for(int i=1;i<=r.n;i++)for(int j=1;j<=r.m;j++)for(int k=1;k<=m;k++)r.c[i][j]= (r.c[i][j]+ (c[i][k] * a.c[k][j])%mod)%mod;return r;}void _print() {for(int i=1;i<=n;i++) {for(int j=1;j<=m;j++) {if(j!=1) cout<<" ";cout<<c[i][j];}if(i!=n) puts("");}}Matrix _power(int indexx) {Matrix tmp,sum;tmp._pre1();sum._pre1();while(indexx>0) {if(indexx&1) sum=sum*tmp;tmp=tmp*tmp;indexx/=2;}return sum;}void _pre1() {n=m=2;c[1][1]=0;c[1][2]=c[2][1]=c[2][2]=1;}void _pre2() {n=1,m=2;c[1][1]=c[1][2]=1;}}T,ans;int main() {cin>>n>>mod;ans._pre2();T._pre1();if(n<=2) { cout<<1; return 0; }T=T._power(n-3);ans=ans*T;cout<<ans.c[1][2]; }那么前n項(xiàng)之和呢?
這里我們可以這么構(gòu)造兩個矩陣:(S(n)為前n項(xiàng)之和)
和將兩個矩陣相乘,剩下的留給讀者思考。
這里給出代碼:
#include <cstdio> #include <cstring> #include <iostream> using namespace std;#define N 10 #define LL long longint n,mod;struct Matrix {LL n,m,c[N][N];Matrix() { memset(c,0,sizeof(c)); };void _read() {for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%lld",&c[i][j]);}Matrix operator * (const Matrix& a) {Matrix r;r.n=n;r.m=a.m;for(int i=1;i<=r.n;i++)for(int j=1;j<=r.m;j++)for(int k=1;k<=m;k++)r.c[i][j]= (r.c[i][j]+ (c[i][k] * a.c[k][j])%mod)%mod;return r;}void _print() {for(int i=1;i<=n;i++) {for(int j=1;j<=m;j++) {if(j!=1) cout<<" ";cout<<c[i][j];}if(i!=n) puts("");}}Matrix _power(int indexx) {Matrix tmp,sum;tmp._pre1();sum._pre1();while(indexx>0) {if(indexx&1) sum=sum*tmp;tmp=tmp*tmp;indexx/=2;}return sum;}void _pre1() {n=m=3;c[3][2]=c[3][3]=c[2][3]=c[1][1]=c[2][1]=c[3][1]=1;}void _pre2() {n=1,m=3;c[1][1]=2;c[1][3]=c[1][2]=1;}}T,ans;int main() {cin>>n>>mod;if(n==2) return printf("%d",2%mod),0;if(n==1) return printf("%d",1%mod),0;ans._pre2();T._pre1();if(n<=2) { cout<<1; return 0; }T=T._power(n-3);ans=ans*T;cout<<ans.c[1][1]; }?
總結(jié)
以上是生活随笔為你收集整理的浅谈矩阵加速——以时间复杂度为O(log n)的算法实现裴波那契数列第n项及前n之和使用矩阵加速法的优化求法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 重力勘探正演模拟matlab,裴雪林,
- 下一篇: android应用程序设计答案,Andr