• 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 <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #define ll long long
    #define mod 6
    using namespace std;
    int n,k;
    struct Matrix
    {
        ll m[6][6];
    };
    
    Matrix I;
    
    Matrix multi(Matrix a,Matrix b)
    {
        Matrix ans;
        for(int i=0;i<k;i++)
        {
            for(int j=0;j<k;j++)
            {
                ans.m[i][j]=0;
                for(int p=0;p<k;p++)
                {
                    ans.m[i][j]+=(a.m[i][p]*b.m[p][j])%mod;
                }
                ans.m[i][j]%=mod;
            }
        }
        return ans;
    }
    
    Matrix power(Matrix a,ll b)
    {
        Matrix ans=I;
        while(b)
        {
            if(b&1)
            {
                ans=multi(ans,a);
            }
            b=b/2;
            a=multi(a,a);
        }
        return ans;
    }
    
    ll A[1005][1005];
    ll B[1005][1005];
    Matrix BA;
    ll tmp[1005][1005];
    ll ans[1005][1005];
    
    int main()
    {
        while(cin>>n>>k)
        {
            if(n==0&&k==0) break;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<k;j++)
                {
                    scanf("%lld",&A[i][j]);
                }
            }
            for(int i=0;i<k;i++)
            {
                for(int j=0;j<n;j++)
                {
                    scanf("%lld",&B[i][j]);
                }
            }
            for(int i=0;i<k;i++)
            {
                for(int j=0;j<k;j++)
                {
                    BA.m[i][j]=0;
                    for(int p=0;p<n;p++)
                    {
                        BA.m[i][j]+=(B[i][p]*A[p][j])%mod;
                    }
                    BA.m[i][j]%=mod;
                }
            }
            memset(I.m,0,sizeof(I.m));
            for(int i=0;i<k;i++)
                I.m[i][i]=1;
            BA=power(BA,n*n-1);
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<k;j++)
                {
                    tmp[i][j]=0;
                    for(int p=0;p<k;p++)
                    {
                        tmp[i][j]+=(A[i][p]*BA.m[p][j])%mod;
                    }
                    tmp[i][j]%=mod;
                }
            }
            ll num=0;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    ans[i][j]=0;
                    for(int p=0;p<k;p++)
                    {
                        ans[i][j]+=(tmp[i][p]*B[p][j])%mod;
                    }
                    ans[i][j]%=mod;
                    num=num+ans[i][j];
                }
            }
            cout<<num<<endl;
        }
        return 0;
    }

           

  • 相关阅读:
    Vue.js整理
    linux~dd命令
    linux 开机自启动的两种方式
    解决mount.nfs: access denied by server while mounting
    pip与apt-get的使用
    Mysql 中字符串的截取
    学生练习:括号匹配
    迷宫问题,打印所有路径,深度搜索,dfs
    vector用法
    【CF1257A】Two Rival Students【思维】
  • 原文地址:https://www.cnblogs.com/simplekinght/p/7087276.html
Copyright © 2020-2023  润新知