矩陣的快速冪是用來高效地計算矩陣的高次方的。將樸素的o(n)的時間複雜度,降到log(n)。
這裡先對原理(主要運用了矩陣乘法的結合律)做下簡單形象的介紹:
一般乙個矩陣的n次方,我們會通過連乘n-1次來得到它的n次冪。
但做下簡單的改進就能減少連乘的次數,方法如下:
把n個矩陣進行兩兩分組,比如:a*a*a*a*a*a => (a*a)*(a*a)*(a*a)
這樣變的好處是,你只需要計算一次a*a,然後將結果(a*a)連乘自己兩次就能得到a^6,即(a*a)^3=a^6。算一下發現這次一共乘了3次,少於原來的5次。
回頭看看矩陣的快速冪問題,我們是不是也能把它離散化呢?比如a^19 => (a^16)*(a^2)*(a^1),顯然採取這樣的方式計算時因子數將是log(n)級別的(原來的因子數是n),不僅這樣,因子間也是存在某種聯絡的,比如a^4能通過(a^2)*(a^2)得到,a^8又能通過(a^4)*(a^4)得到,這點也充分利用了現有的結果作為有利條件。下面舉個例子進行說明:
現在要求a^156,而156(10)=10011100(2)
也就有a^156=>(a^4)*(a^8)*(a^16)*(a^128) 考慮到因子間的聯絡,我們從二進位制10011100中的最右端開始計算到最左端。細節就說到這,下面給核心**:
1 while(n)
2 裡面的乘號,是矩陣乘的運算,res是結果矩陣。
第3行**每進行一次,二進位制數就少了最後面的乙個1。二進位制數有多少個1就第3行**就執行多少次。
poj 3070 矩陣加速求斐波那契數列**:
#include #include#include
#include
using
namespace
std;
int n = 2
, m;
int s[2][2]=, };
struct
matrix
res, origin;
void
init()
origin.c =n;
origin.r =n;
for(int i = 1; i <= n; i++)
}matrix multi(matrix x, matrix y)}}
//for(i=1;i<=2;i++)
////}//
}returnt;}
intmain()
origin =multi(origin, origin);
m = m >> 1
; }
printf(
"%d\n
", res.mat[1][2] % 10000
); }
return0;
}
矩陣專題 矩陣加速 矩陣快速冪
矩陣有乙個神奇的作用,它可以用來快速求遞推式的第 n 項,學會這個技 能,你需要掌握這兩個前置芝士 矩陣快速冪,矩陣加速 數列 具體怎麼優化呢?這個部落格已經總結的較為全面,在這裡我就不再加贅述。貼一發我寫的模板 include include include include define int ...
快速冪,矩陣乘法,矩陣快速冪
快速冪利用二進位制 複雜度 log級 include include include include using namespace std typedef long long ll typedef unsigned long long ull int q power int a,int b,int...
快速冪(矩陣快速冪)
求 3 0 3 1 3 n mod 1000000007 input 輸入乙個數n 0 n 10 9 output 輸出 計算結果 sample input 3sample output 40 分析 利用等比數列的求和公式得所求和是 3 n 1 1 2,如果暴力求3 n 1 會超時,這裡引入快速冪來...