Bootstrap

hdoj 1575 Tr A (矩阵快速幂)

Tr A

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4549    Accepted Submission(s): 3428


Problem Description
A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。
 

Input
数据的第一行是一个T,表示有T组数据。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。
 

Output
对应每组数据,输出Tr(A^k)%9973。
 

Sample Input
  
  
  
2 2 2 1 0 0 1 3 99999999 1 2 3 4 5 6 7 8 9
 

Sample Output
  
  
  
2 2686
 
矩阵快速幂 求模
代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#define mod 9973
using namespace std;
struct Matrix
{
    int A[20][20];
    int r,c;//矩阵行列,这一题行列均为n
};
Matrix ori,res;
int n;
void Init(int n)
{
    memset(res.A,0,sizeof(res.A));//矩阵初始化
    for(int i=0;i<n;i++)
    {
        res.A[i][i]=1;
        for(int j=0;j<n;j++)
        {
            scanf("%d",&ori.A[i][j]);
        }
    }
}
//矩阵乘法
Matrix multiple(Matrix a,Matrix b)
{
    Matrix c;
    memset(c.A,0,sizeof(c.A));
    for(int i=0;i<n;i++)
    {
        for(int k=0;k<n;k++)
        {
            if(a.A[i][k]==0) continue;
            for(int j=0;j<n;j++)
            {
                c.A[i][j]=(c.A[i][j]+(a.A[i][k]*b.A[k][j])%mod)%mod;
            }
        }
    }
    return c;//返回”矩阵“结构体
}
//矩阵快速幂
void Matrix_mod(Matrix ori,int k)
{
    while(k)
    {
        if(k&1)
            res=multiple(ori,res);
        ori=multiple(ori,ori);
        k>>=1;
    }
    int  ans=0;
    for(int i=0;i<n;i++)
    {
        ans=(ans+res.A[i][i])%mod;
    }
    printf("%d\n",ans);
}
int main()
{
    int t,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        Init(n);
        Matrix_mod(ori,k);
    }
    return 0;
}

第一道矩阵快速幂,和普通快速幂差不多,只不过这里是矩阵的运算和取模。
转自:点击打开链接
转载一个写的可好的详解

基础知识:(会基础的直接看应用部分)

(1)矩阵乘法

简单的说矩阵就是二维数组,数存在里面,矩阵乘法的规则:A*B=C


其中c[i][j]为A的第i行与B的第j列对应乘积的和,即:

代码:

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. const int N=100;  
  2. int c[N][N];  
  3. void multi(int a[][N],int b[][N],int n)  
;