看来还是要吧这个矩阵乘法理解透啊!
我的题解大体和网上的一样吧。没有什么可取性。
对于矩阵,我们熟悉的操作有两种,交换与置零。
我们有初始的矩阵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 111
using 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;
}