C++-POJ3735-Training little cats[矩阵乘法][快速幂]

矩阵快速幂,主要是考构造。另外,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 }
~~Jason_liu O(∩_∩)O
原文地址:https://www.cnblogs.com/JasonCow/p/12359789.html