題目:http://poj.org/problem?id=3233html
這是今天考試的題目,結果沒想出來寫了個暴力30分,看完題解以後以爲本身是SBios
首先暴力就是一個個乘而後相加,時間是O(kn3),極限數據要跑一個月才跑得出來函數
咱們思考,求冪的話有快速冪(不會快速冪戳這裏: http://www.cnblogs.com/hadilo/p/5719139.html ),那麼矩陣同樣也是能夠的是否是spa
由於對於方陣A來講,(A2)2=A4
3d
因而實數怎樣作快速冪,矩陣就怎樣作code
1 while (m>0) 2 { 3 if (m%2) mult(b,a); 4 m/=2; 5 mult(a,a); 6 }
手寫一個 mult 函數,就用最普通的 n3 矩陣乘法htm
(矩陣的基本運算,通俗易懂 http://www.cnblogs.com/hadilo/p/5865541.html)blog
1 void mult(int x[N][N],int y[N][N]) 2 { 3 int i,j,k; 4 for (i=1;i<=n;i++) 5 for (j=1;j<=n;j++) 6 { 7 c[i][j]=0; 8 for (k=1;k<=n;k++) c[i][j]=(c[i][j]+x[i][k]*y[k][j])%mo; 9 } 10 for (i=1;i<=n;i++) 11 for (j=1;j<=n;j++) x[i][j]=c[i][j]; 12 }
但題目要求的是 A+A2+...+Ak,而不是單個矩陣的冪get
那麼咱們能夠構造一個分塊的輔助矩陣 S,其中 A 爲原矩陣,E 爲單位矩陣,O 爲0矩陣string
咱們將 S 取冪,會發現一個特性
Sk 右上角那一塊不正是咱們要求的 A+A2+...+Ak 嗎?
因而咱們構造出 S 矩陣,而後對它求矩陣快速冪便可,最後別忘了減去一個單位陣
時間降爲O(n3log2k),從一個月到0.8秒的跨越
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 9 const int N=61; 10 int c[N][N],a[N][N],b[N][N],n,mo; 11 void mult(int x[N][N],int y[N][N]) 12 { 13 int i,j,k; 14 for (i=1;i<=n;i++) 15 for (j=1;j<=n;j++) 16 { 17 c[i][j]=0; 18 for (k=1;k<=n;k++) c[i][j]=(c[i][j]+x[i][k]*y[k][j])%mo; 19 } 20 for (i=1;i<=n;i++) 21 for (j=1;j<=n;j++) x[i][j]=c[i][j]; 22 } 23 int main() 24 { 25 int m,i,j; 26 scanf("%d%d%d",&n,&m,&mo); 27 for (i=1;i<=n;i++) 28 { 29 for (j=1;j<=n;j++) scanf("%d",&a[i][j]); 30 a[i][i+n]=a[i+n][i+n]=b[i][i]=b[i+n][i+n]=1; 31 } 32 n*=2; 33 m++; 34 while (m>0) 35 { 36 if (m%2) mult(b,a); 37 m/=2; 38 mult(a,a); 39 } 40 n/=2; 41 for (i=1;i<=n;i++) b[i][i+n]--; 42 for (i=1;i<=n;i++) 43 { 44 for (j=1;j<n;j++) printf("%d ",b[i][j+n]); 45 printf("%d\n",b[i][j+n]); 46 } 47 return 0; 48 }
版權全部,轉載請聯繫做者,違者必究
QQ:740929894