POJ3233不错的矩阵(矩阵套矩阵)
生活随笔
收集整理的這篇文章主要介紹了
POJ3233不错的矩阵(矩阵套矩阵)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? ?給一個n*n的矩陣A,然后求S=A + A^2 + A^3 + ..+ A^k.
思路:
? ? ? 矩陣快速冪,這個題目挺新穎的,以往的矩陣快速冪都是退出公式,然后構造矩陣,這個比較特別,直接上子矩陣吧
A 1 ? 平方后得到 A^2 1+A ?三次方 ? A^3 ? 1+A+A^2
0 1 ? ? ? ? ? ? ? 0 ? 1 ? ? ? ? ? ? 0 ? ? 1 ? ? ? ...這樣就行了,
還有注意這個是矩陣套矩陣,然后就是快速冪了,比較容易實現,有一點要注意,
? ? ? ?給一個n*n的矩陣A,然后求S=A + A^2 + A^3 + ..+ A^k.
思路:
? ? ? 矩陣快速冪,這個題目挺新穎的,以往的矩陣快速冪都是退出公式,然后構造矩陣,這個比較特別,直接上子矩陣吧
A 1 ? 平方后得到 A^2 1+A ?三次方 ? A^3 ? 1+A+A^2
0 1 ? ? ? ? ? ? ? 0 ? 1 ? ? ? ? ? ? 0 ? ? 1 ? ? ? ...這樣就行了,
還有注意這個是矩陣套矩陣,然后就是快速冪了,比較容易實現,有一點要注意,
大矩陣的單位矩陣只有對角線才是單位小矩陣,還有一個地方,就是最后我們要在大矩陣的1 2 位置減去單位矩陣,這個減去單位矩陣后如果比0小怎么辦,我的處理方法是比0小就再加上余數。
#include<stdio.h> #include<string.h>typedef struct {int mat[32][32]; }M;typedef struct {M MAT[3][3]; }MM;int n ,MOD;M matM(M a ,M b) {M c;memset(c.mat ,0 ,sizeof(c.mat));for(int k = 1 ;k <= n ;k ++)for(int i = 1 ;i <= n ;i ++)if(a.mat[i][k])for(int j = 1 ;j <= n ;j ++)c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;return c; }M addM(M a ,M b) {M c;memset(c.mat ,0 ,sizeof(c.mat));for(int i = 1 ;i <= n ;i ++)for(int j = 1 ;j <= n ;j ++)c.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % MOD;return c; }MM matMM(MM a ,MM b) {MM c;for(int i = 1 ;i <= 2 ;i ++)for(int j = 1 ;j <= 2 ;j ++)for(int k = 1 ;k <= n ;k ++)for(int l = 1 ;l <= n ;l ++)c.MAT[i][j].mat[k][l] = 0;for(int i = 1 ;i <= 2 ;i ++)for(int j = 1 ;j <= 2 ;j ++)for(int k = 1 ;k <= 2 ;k ++)c.MAT[i][j] = addM(c.MAT[i][j] ,matM(a.MAT[i][k] ,b.MAT[k][j]));return c; }MM quickMM(MM a ,int b) {MM c;for(int i = 1 ;i <= 2 ;i ++)for(int j = 1 ;j <= 2 ;j ++)for(int k = 1 ;k <= n ;k ++)for(int l = 1 ;l <= n ;l ++)c.MAT[i][j].mat[k][l] = 0;for(int k = 1 ;k <= n ;k ++)c.MAT[1][1].mat[k][k] = c.MAT[2][2].mat[k][k] = 1;while(b){if(b & 1) c = matMM(c ,a);a = matMM(a ,a);b >>= 1;}return c; }int main () {int i ,j ,b;MM A;while(~scanf("%d %d %d" ,&n ,&b ,&MOD)){//MOD = 10000000;for(i = 1 ;i <= n ;i ++)for(j = 1 ;j <= n ;j ++){scanf("%d" ,&A.MAT[1][1].mat[i][j]);A.MAT[2][1].mat[i][j] = 0;if(i == j)A.MAT[1][2].mat[i][j] = A.MAT[2][2].mat[i][j] = 1;else A.MAT[1][2].mat[i][j] = A.MAT[2][2].mat[i][j] = 0;}MM ans = quickMM(A ,b + 1);for(int i = 1 ;i <= n ;i ++)for(int j = 1 ;j <= n ;j ++){if(i == j) ans.MAT[1][2].mat[i][j] --;if(ans.MAT[1][2].mat[i][j] < 0) ans.MAT[1][2].mat[i][j] += MOD;if(j == n) printf("%d\n",ans.MAT[1][2].mat[i][j]);else printf("%d " ,ans.MAT[1][2].mat[i][j]);}}return 0;}
總結
以上是生活随笔為你收集整理的POJ3233不错的矩阵(矩阵套矩阵)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ3122贪心或者二分(分蛋糕)
- 下一篇: POJ3614奶牛晒阳光DINIC或者贪