1. 程式人生 > >算法筆記--矩陣快速冪

算法筆記--矩陣快速冪

sub display closed def i++ struct 構造 博客 using

寫的不錯的博客:http://www.cnblogs.com/yan-boy/archive/2012/11/29/2795294.html

優點:根據數列遞推式快速計算數列an的值(當n很大時)

步驟:由數列遞推式構造矩陣,然後用矩陣快速冪計算矩陣的冪。

構造矩陣:對於an =x*an-1 +y*an-2 ,可以構造矩陣為:

[an ,an-1]=[an-1 ,an-2]*A

A=[x 1

  y 0];

矩陣快速冪模板:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm> 
using
namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int MOD=10000; struct Matrix { ll a[2][2]; }A,res; Matrix multiply(Matrix x,Matrix y) { Matrix res; mem(res.a,0); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int
k=0;k<2;k++) res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%MOD; return res; } void qpow(int n) { while(n) { if(n&1)res=multiply(res,A); A=multiply(A,A); n=n>>1; } }

例題1:POJ 3070 Fibonacci

代碼:

技術分享
#include<iostream>
#include<cstring>
#include
<cstdio> #include<algorithm> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int MOD=10000; struct Matrix { ll a[2][2]; }A,res; Matrix multiply(Matrix x,Matrix y) { Matrix res; mem(res.a,0); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%MOD; return res; } void qpow(int n) { while(n) { if(n&1)res=multiply(res,A); A=multiply(A,A); n=n>>1; } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; while(cin>>n) { if(n==-1)break; mem(res.a,0); for(int i=0;i<2;i++)res.a[i][i]=1; A.a[0][0]=1; A.a[0][1]=1; A.a[1][0]=1; A.a[1][1]=0; qpow(n); cout<<res.a[0][1]<<endl; } return 0; }
View Code

算法筆記--矩陣快速冪