POJ3070 -矩陣快速冪 模板
阿新 • • 發佈:2018-12-11
今天在補acmicpc焦作網路預選賽題,補L題時發現看不懂程式碼,後來學長告訴我這個程式碼用的是矩陣快速冪,還有一種演算法是杜教BM自動機,這個以後再說,於是自己便找了個矩陣快速冪的模板題學習一下。
矩陣快速冪的作用是簡化遞推的過程,比如斐波那契數列就可以用矩陣快速冪來表示通過矩陣乘法可以得到f(n)=f(n-1)+f(n-2) 圖中矩陣乘法可以看成T*a(n-1)=a(n) 其中T為常數矩陣,向下回溯可以得到A(n)=T^n-1*a1其中a1為初始矩陣也就是當n=1時的值,那麼答案就是res[1][1](res是等號後面的矩陣)具體的可以參見大佬寫的矩陣快速冪總結很詳細
在這道題中就用到上圖的表示;
程式碼:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 2; const int mod = 1e+4; struct Matrix { int mat[maxn][maxn]; Matrix(){} Matrix operator *(Matrix const &b)const { Matrix res; memset(res.mat, 0, sizeof(res.mat)); for (int i = 0; i < maxn; i++) for (int j = 0; j < maxn; j++) for (int k = 0; k < maxn; k++) res.mat[i][j] = (res.mat[i][j] + this->mat[i][k] * b.mat[k][j]) % mod; return res; } }; Matrix Quickpow(Matrix base, int n) { Matrix res; memset(res.mat, 0, sizeof(res.mat)); for (int i = 0; i < maxn; i++) res.mat[i][i] = 1; while (n>0) { if (n & 1) res = res * base; base = base * base; n >>= 1; } return res; } int main() { Matrix base; for (int i = 0; i < maxn; i++) for (int j = 0; j < maxn; j++) base.mat[i][j] = 1; base.mat[1][1] = 0; int n; while (~scanf("%d", &n) && n != -1) { if (n != 0) { Matrix ans = Quickpow(base, n - 1); printf("%d\n", ans.mat[0][0]); } else printf("0\n"); } system("pause"); return 0; }