POJ3233_Matrix Power Series_矩陣冪_C++

  題目: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.htmlblog

 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+...+A嗎?

  因而咱們構造出 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

相關文章
相關標籤/搜索