hdu4965Fast Matrix Calculation 矩阵快速幂

来源:互联网 发布:性价比 实木家具 知乎 编辑:程序博客网 时间:2024/04/30 09:47
//给一个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 ;}
0 0