hdu4965Fast Matrix Calculation 矩阵快速幂

//给一个n*k的矩阵A和一个k*n的矩阵B(n <= 1000) , (k <= 6)
//C = A*B
//求M = C^(n*n)
//M = A*B*A*B... = A*(B*A)^(n*n-1)*B
//中间用快速幂做
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 1010 ;
const int mod = 6 ;
struct node
{
    int p[10][10] ;
};

node mul(node a , node b , int n)
{
    node c ;
    for(int i = 1;i <= n;i++)
      for(int j = 1;j <= n;j++)
      {
          c.p[i][j] = 0 ;
          for(int s = 1;s <= n;s++)
          c.p[i][j] = (c.p[i][j] + a.p[i][s]*b.p[s][j])%mod ;
      }
    return c ;
}
node pow(node a ,int n , int k)
{
    node c ;
    memset(c.p , 0 , sizeof(c.p)) ;
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n;j++)
        c.p[i][i] = 1 ;
    while(k)
    {
        if(k&1)c = mul(c , a , n) ;
        a = mul(a , a ,  n) ;
        k >>= 1 ;
    }
    return c ;
}
int ans[maxn][maxn] ;
int main()
{
    //freopen("in.txt" , "r" , stdin) ;
    int n , k ;
    while(scanf("%d%d" , &n , &k) && (n+k))
    {
        int a[maxn][10] ;
        int b[10][maxn] ;
        for(int i = 1;i <= n;i++)
          for(int j = 1;j <= k;j++)
          scanf("%d" , &a[i][j]) ;
        for(int i = 1;i <= k;i++)
          for(int j = 1;j <= n;j++)
          scanf("%d" , &b[i][j]) ;
        node c ;
        memset(c.p , 0 , sizeof(c.p)) ;

        for(int i = 1;i <= k;i++)
          for(int j = 1;j <= k;j++)
            for(int s = 1;s <= n;s++)
            c.p[i][j] = (c.p[i][j] + b[i][s]*a[s][j])%mod ;

        c = pow(c , k , n*n-1) ;

        int tmp[maxn][10] ;
        memset(tmp , 0 , sizeof(tmp)) ;
        for(int i = 1;i <= n;i++)
          for(int j = 1;j <= k;j++)
            for(int s = 1;s <= k;s++)
            tmp[i][j] = (tmp[i][j] + a[i][s]*c.p[s][j])%mod ;

        memset(ans , 0 , sizeof(ans)) ;
        for(int i = 1;i <= n;i++)
          for(int j = 1;j <= n;j++)
            for(int s = 1;s <= k;s++)
            ans[i][j] = (ans[i][j] + tmp[i][s]*b[s][j])%mod ;

        int sum = 0 ;
        for(int i = 1;i <= n;i++)
          for(int j = 1;j <= n;j++)
          sum += ans[i][j] ;
        printf("%d\n" , sum) ;
    }
    return  0 ;
}

你可能感兴趣的:(矩阵快速幂)