HDU_4965 Fast Matrix Calculation 2014多校9 矩阵快速幂+机智的矩阵结合律

一开始看这个题目以为是个裸的矩阵快速幂的题目,

后来发现会超时,超就超在  M = C^(N*N). 这个操作,而C本身是个N*N的矩阵,N最大为1000。

但是这里有个巧妙的地方就是 C的来源其实 是= A*B, A为一个N*k的矩阵,B为一个k*N的矩阵,k最大为10,突破的就在这里,矩阵的结合律要用起来

即我先不把A*B结合,我先把B*A结合,这样M不是要C^N*N吗,就先把里面N*N个(B*A)算出来,就10*10再乘以logN*N即可。最后再两端乘一下A和B即可

也挺机智的,我没想到结合律。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL __int64
using namespace std;
LL matA[1010][10],matB[10][1010];
LL matC[1010][10];
LL MM[1010][1010];
int n,k;
struct Mat
{
    LL mat[10][10];
}E;
Mat operator *(Mat a,Mat b)
{
    Mat c;
    for (int i=0;i<k;i++)
    for (int j=0;j<k;j++){
        c.mat[i][j]=0;
        for (int w=0;w<k;w++){
            c.mat[i][j]+=a.mat[i][w]*b.mat[w][j];
            c.mat[i][j]%=6;
        }
    }
    return c;
}
Mat operator ^(Mat a,int x)
{
    Mat c=E;
    for (int i=x;i;i>>=1){
        if (i&1){
            c=c*a;
        }
        a=a*a;
    }
    return c;
}
int main()
{
    memset(E.mat,0,sizeof E.mat);
    for (int i=0;i<10;i++) E.mat[i][i]=1;
    while (scanf("%d%d",&n,&k)!=EOF)
    {
        if (n==0 && k==0) break;
        for (int i=0;i<n;i++)
            for (int j=0;j<k;j++) scanf("%I64d",&matA[i][j]);
        for (int i=0;i<k;i++)
            for (int j=0;j<n;j++) scanf("%I64d",&matB[i][j]);
        Mat a;
        for (int i=0;i<k;i++)
            for (int j=0;j<k;j++){
               a.mat[i][j]=0;
               for (int w=0;w<n;w++){
                 a.mat[i][j]+=matB[i][w]*matA[w][j];
               }
               //cout<<i<<" aaa "<<j<<" "<<a.mat[i][j]<<endl;
            }

        Mat M=a^(n*n-1);

        for (int i=0;i<n;i++)
        for (int j=0;j<k;j++){
            matC[i][j]=0;
            for (int w=0;w<k;w++)
                 matC[i][j]+=matA[i][w]*M.mat[w][j];
           // cout<<matC[i][j]<<" Matc "<<endl;
        }
        int ans=0;
        for (int i=0;i<n;i++)
        for (int j=0;j<n;j++){
            MM[i][j]=0;
            for (int w=0;w<k;w++){
                MM[i][j]+=matC[i][w]*matB[w][j];
            }
           // cout<<MM[i][j]<<" qwe "<<endl;
            ans+=MM[i][j]%6;
        }
        printf("%d\n",ans);
    }
    return 0;

}

  

时间: 2024-10-05 13:35:06

HDU_4965 Fast Matrix Calculation 2014多校9 矩阵快速幂+机智的矩阵结合律的相关文章

HDU 4965 Fast Matrix Calculation (矩阵快速幂取模----矩阵相乘满足结合律)

http://acm.hdu.edu.cn/showproblem.php?pid=4965 利用相乘的可结合性先算B*A,得到6*6的矩阵,利用矩阵快速幂取模即可水过. 1 #include<iostream> 2 #include<stdio.h> 3 #include<iostream> 4 #include<stdio.h> 5 #define N 1010 6 #define M 1010 7 #define K 6 8 using namespa

hdu 4965 Fast Matrix Calculation(矩阵快速幂)2014多校训练第9场

Fast Matrix Calculation                                                                   Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description One day, Alice and Bob felt bored again, Bob knows Ali

HDOJ 4965 Fast Matrix Calculation

(AB)^n=A*(BA)^(n-1)^B Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 576    Accepted Submission(s): 297 Problem Description One day, Alice and Bob felt bored again, B

HDU 4965 Fast Matrix Calculation(矩阵高速幂)

题目大意:给你两个数字n和k,然后给你两个矩阵a是n*k的和b是k*n的,矩阵c = a*b,让你求c^(n*n). 直接求的话c是n*n的矩阵所以是1000*1000.会超时的啊. 能够转化一下:(a*b)^(n*n)=a*(b*a)^(n*n-1)*b.b*a能够得到一个k*k的矩阵,k非常小所以不会超时.高速幂一下就能够了啊. Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 13

HDU 4965 Fast Matrix Calculation 【矩阵】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4965 题目大意:给你一个N*K的矩阵A以及一个K*N的矩阵B (4 <= N <= 1000)以及 (2 <=K <= 6),然后接下来四步: 算一个新的矩阵C=A*B 算M=C^ (N*N) 对于M中的每个元素%6 将M中每个元素加起来,算出和. 也就是求出A*B * A*B * A*B * A*B * A*B *--* A*B   但是A*B形成的矩阵是N*N,而N大小有可能是10

hdu 4965 Fast Matrix Calculation(矩阵快速幂)

题目链接:hdu 4965 Fast Matrix Calculation 题目大意:给定两个矩阵A,B,分别为N*K和K*N: 矩阵C = A*B 矩阵M=CN?N 将矩阵M中的所有元素取模6,得到新矩阵M' 计算矩阵M'中所有元素的和 解题思路:因为矩阵C为N*N的矩阵,N最大为1000,就算用快速幂也超时,但是因为C = A*B, 所以CN?N=ABAB-AB=AC′N?N?1B,C' = B*A, 为K*K的矩阵,K最大为6,完全可以接受. #include <cstdio> #inc

HDU 4965 Fast Matrix Calculation(矩阵快速幂)

HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次,可以变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个只有6x6,就可以用矩阵快速幂搞了 代码: #include <cstdio> #include <cstring> const int N = 1005; const int M = 10; int n, m; int A[N][M], B[M][N], C[M][M], CC[N]

HDU 4965 Fast Matrix Calculation(矩阵高速幂)

HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次.能够变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个仅仅有6x6.就能够用矩阵高速幂搞了 代码: #include <cstdio> #include <cstring> const int N = 1005; const int M = 10; int n, m; int A[N][M], B[M][N], C[M][M], CC[N

hdu 4965 Fast Matrix Calculation(矩阵快速幂)

题意: 给你一个N*K的矩阵A和一个K*N的矩阵B,设矩阵C=AB,M=C^(N*N),矩阵Mmod6后,所有数的和是多少 思路: 刚开始我是直接计算的,开了一个1000*1000的矩阵,结果直接爆掉了 后来看了看题解,发现想的很巧妙 观察 M=ABABAB....AB,AB每次都是1000*1000,可是BA确是6*6的 那么 M=A(BABABA..BA)B,我们让BA进行矩阵快速幂就不会爆掉了 M=A(BA)^(N*N-1)B,最后计算一下就好了 代码: #include <iostrea