矩阵快速幂,主要是考构造。另外,swap总是写龊?
为什么?干脆放弃了。唉,我太难了。
思路:操作e和s都很好想,主要是g操作
我们可以额外空出一位,记为1,每次要加1,就对这个额外的1进行计算即可
不妨定义A=[1 0 0 ... 0],此时只要构造一组操作的等效矩阵T就好了
就是添一位使初始矩阵A变为一个n+1元组,编号为0到n。以三只猫为例[1 0 0 0]
1 #include <cstdio> 2 typedef long long ll; 3 const int N=105; 4 int n,m,k;ll t; 5 struct Matrix{ll a[N][N];}O,I; 6 void OI(){ 7 for(int i=0;i<N;i++) 8 for(int j=0;j<N;j++) 9 O.a[i][j]=0,I.a[i][j]=(i==j); 10 } 11 Matrix Mul(Matrix A,Matrix B) { 12 Matrix C=O; 13 for(int k=0;k<=n;k++) 14 for(int i=0;i<=n;i++) 15 if(A.a[i][k])//注意这个优化 16 for(int j=0;j<=n;j++) 17 C.a[i][j]+=A.a[i][k]*B.a[k][j]; 18 return C; 19 } 20 Matrix Pow(Matrix A,int n){ 21 Matrix B=I; 22 for(;n;A=Mul(A,A),n>>=1)if(n&1)B=Mul(B,A); 23 return B; 24 } 25 Matrix makeA(){Matrix A=O;A.a[0][0]=1;return A;} 26 Matrix makeT(){ 27 Matrix T=I;char s[5];int a,b,i; 28 while(k--){ 29 scanf("%s%d",s,&a); 30 if(s[0]==‘g‘)T.a[0][a]++; 31 else if(s[0]==‘e‘)for(i=0;i<=n;i++)T.a[i][a]=0; 32 else for(scanf("%d",&b),i=0;i<=n;i++)t=T.a[i][a],T.a[i][a]=T.a[i][b],T.a[i][b]=t; 33 } 34 return T; 35 } 36 int main(){ 37 OI(); 38 while(scanf("%d%d%d",&n,&m,&k)!=EOF){ 39 if(n==0&&m==0&&k==0)break; 40 Matrix A=makeA(),T=makeT();A=Mul(A,Pow(T,m)); 41 for(int i=1;i<=n;i++)printf("%lld ",A.a[0][i]); 42 puts(""); 43 } 44 return 0; 45 }
原文地址:https://www.cnblogs.com/JasonCow/p/12359789.html
时间: 2024-10-07 15:22:09