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