题目链接:http://poj.org/problem?id=3735
解题思路:
先构造一个(n+1)*(n+1)的单位矩阵E,在此基础上进行操作:
1、g i -------------> E[0][i] ++;
2、s i j -------------> for(int k=0;k<=n;k++) swap(E[k][i],E[k][j]);
3、e i -------------> for(int k=0;k<=n;k++) E[k][i]=0;
上面的这一个部分本来我是构造多个单位矩阵,在单位矩阵上进行操作的,操作后的矩阵相乘的结果就是总的操作,结果就是一个TLE。。。后来改成这样才AC了。
然后再构造一个矩阵A,A只有左上角为1,其他的都为0。操作m次,其实就是A*(E^m)。矩阵快速幂,上!
AC代码:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 const int maxn=110; 8 struct Matrix{ 9 ll mat[maxn][maxn]; 10 }; 11 Matrix Multiply(Matrix x,Matrix y,int n){ 12 Matrix temp; 13 for(int i=0;i<=n;i++){ 14 for(int j=0;j<=n;j++){ 15 temp.mat[i][j]=0; 16 for(int k=0;k<=n;k++){ 17 if(x.mat[i][k]&&y.mat[k][j]) //没有这个优化TLE 18 temp.mat[i][j]+=(x.mat[i][k]*y.mat[k][j]); 19 } 20 } 21 } 22 return temp; 23 } 24 Matrix Fast_Power(Matrix a,int m,int n){ 25 Matrix res; 26 for(int i=0;i<=n;i++){ 27 for(int j=i;j<=n;j++){ 28 if(i==j) res.mat[i][j]=1; 29 else res.mat[i][j]=res.mat[j][i]=0; 30 } 31 } 32 while(m){ 33 if(m&1) res=Multiply(res,a,n); 34 m>>=1; 35 a=Multiply(a,a,n); 36 } 37 return res; 38 } 39 40 int main(){ 41 Matrix rt; 42 int n,m,k,a,b; 43 char t[3]; 44 while(scanf("%d%d%d",&n,&m,&k)==3&&(n||m||k)){ 45 for(int i=0;i<=n;i++){ 46 for(int j=i;j<=n;j++){ 47 if(i==j) rt.mat[i][j]=1; 48 else rt.mat[i][j]=rt.mat[j][i]=0; 49 } 50 }//构造出一个(n+1)*(n+1)的单位矩阵 51 while(k--){ 52 scanf("%s",t); 53 if(t[0]=='g'){ 54 scanf("%d",&a); 55 rt.mat[0][a]++; 56 } 57 else if(t[0]=='e'){ 58 scanf("%d",&a); 59 for(int i=0;i<=n;i++) 60 rt.mat[i][a]=0; 61 } 62 else{ 63 scanf("%d %d",&a,&b); 64 for(int i=0;i<=n;i++){ 65 if(rt.mat[i][a]||rt.mat[i][b]) 66 swap(rt.mat[i][a],rt.mat[i][b]); 67 } 68 } 69 } 70 if(m==0){ 71 for(int i=0;i<n;i++){ 72 if(i!=0) printf(" "); 73 printf("0"); 74 } 75 } 76 else{ 77 Matrix t; 78 memset(t.mat,0,sizeof(t)); 79 t.mat[0][0]=1; 80 Matrix ret=Multiply(t,Fast_Power(rt,m,n),n); 81 for(int i=1;i<=n;i++){ 82 if(i!=1) printf(" "); 83 printf("%lld",ret.mat[0][i]); 84 } 85 } 86 printf(" "); 87 } 88 return 0; 89 }