看來還是要吧這個矩陣乘法理解透啊!
我的題解大體和網上的一樣吧。沒有什麼可取性。
對於矩陣,我們熟悉的操作有兩種,交換與置零。
我們有初始的矩陣T[ A,B,C,D ];
交換矩陣為
| 1 0 0 0 |
[ A,B,C,D ] X | 0 0 1 0 | =>[ A C B D ]
| 0 1 0 0 |
| 0 0 0 1 |
置零矩陣為
| 1 0 0 0 |
[ A,B,C,D ] X | 0 1 0 0 | =>[ A B 0 D ]
| 0 0 0 0 |
| 0 0 0 1 |
接下來的問題就是+1 操作了
| 1 1 0 0 |
[ 1,B,C,D ] X | 0 1 0 0 | =>[ 1,B+1,C,D ]
| 0 0 1 0 |
| 0 0 0 1 |
然後用矩陣的快速冪就可以了。
#include<iostream>#include<string.h>#include<cstdio>#define MAXN 111using namespace std;typedef long long ll;int n,m,k;struct node{ ll ma[MAXN][MAXN];};node matrix,res;node matriXmult( node a,node b ){ node c; memset( c.ma,0,sizeof(c.ma) ); for( int i=0;i<=n;i++ ) for( int k=0;k<=n;k++ ) if( a.ma[i][k] ) for( int j=0;j<=n;j++ ) c.ma[i][j]+=a.ma[i][k]*b.ma[k][j]; return c;}int main(){ while( scanf("%d%d%d",&n,&m,&k)&&n|k|m ) { memset( matrix.ma,0,sizeof(matrix.ma) ); for( int i=0;i<=n;i++ ) matrix.ma[i][i]=1; while( k-- ) { char command; int x,y; scanf( "\n%c",&command ); if( command=='g' ){ scanf( "%d",&x ); matrix.ma[0][x]++; } else if( command=='e' ){ scanf( "%d",&x ); for( int i=0;i<=n;i++ ) matrix.ma[i][x]=0; } else if( command=='s' ){ scanf( "%d %d",&x,&y ); for( int i=0;i<=n;i++ ) swap( matrix.ma[i][x],matrix.ma[i][y] ); } } memset( res.ma,0,sizeof(res.ma) ); for( int i=0;i<=n;i++ ) res.ma[i][i]=1; for( int i=0;i<31;i++ ){ if( m&(1<<i) ) res=matriXmult( res,matrix ); matrix=matriXmult( matrix,matrix ); } printf( "%I64d",res.ma[0][1] ); for( int i=2;i<=n;i++ ) printf( " %I64d",res.ma[0][i] ); putchar('\n'); } return 0;}