矩陣快速冪
一、例:
斐波那契數列

第一個矩陣是轉移矩陣記為s,第二個矩陣是當前狀態dp[n],等號右邊是下一狀態記為dp[n+1];
二、當需要遞推K次時:
s的K次方*dp[1]=dp[K];
所以s可以利用快速冪的思想來求(注意:快速冪以2為底倍增,事實上你可以用任何大小作為底,只要能更快的求出你想要的結果;詳見牛客多校2019-8-1第五場 B)
一些簡單的遞推式:
1.f(n)=a*f(n-1)+b*f(n-2)+c;(a,b,c是常數)

2.f(n)=c^n-f(n-1) ;(c是常數)

三、板子:
-
struct Mat { ///結構體,矩陣類型 int m[M][M]; } res,e; void init_e(){ //整數快速冪默認的ans是1,矩陣的話ans應為單位矩陣 for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) e.m[i][j]=1; else e.m[i][j]=0; } } } Mat Mul(Mat a,Mat b,int n) { Mat tmp;//定義一個臨時的矩陣,存放A*B的結果 for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { tmp.m[i][j] = 0; } } for(itn i=1; i <= n; i++) { for(int j = 1; j <= n; j++) { for(int k = 1; k <= n; k++) { tmp.m[i][j] += a.m[i][k]*b.m[k][j]; } } } return tmp; } ///矩陣快速冪,求矩陣res的N次冪 Mat Mat_qpower(Mat base,int K){ res=e; while(K) { if(K&1) res=Mul(res,base); base=Mul(base,base); K=K>>1; } return res; }
