---恢复内容开始---

题意:已知n*n的矩阵A和正整数k,求S = A + A^2 + A^3 + .... + A^k并输出S的各元素对M取余后的答案。

分析:如果选择依次求解矩阵的幂,然后将其累加,时间复杂度是O(kn^3logk),效率太低。但如果试着找一下关于S的递推公式,效率将大大提升。

我们不妨令S(k) = I + A + A^2 + ... + A^(k-1),则有(A^k, S(k))= ((A, 0), (I, I) )* (A^(k-1), S(k-1))= ((A, 0), (I, I))^k * (I, 0)。

令矩阵B = ((A, 0), (I, I)),则原问题转化为求B^(k+1),时间复杂度为O(n^3logk)。

代码实现:

void solve(mat A, int n, int k, int M)

{

  mat B(2*n, vec(2*n));

  for(int i = 0; i < n; ++i)

    for(int j = 0; j < n; ++j)

    {

      B[i][j] = A[i][j];

      B[n+i][i] = B[n+i][n+i] = 1;//构造单位矩阵I

    }

  B = pow(B, k + 1);//求B^(k+1)

  for(int i = 0; i < n; ++i)

    for(int j = 0; j < n; ++j)

    {

      int a = (B[i + n][j]) % M;

      if(i == j)

        a = (a + M - 1) % M;

      cout << a << endl;

    }

}

---恢复内容结束---