zoukankan      html  css  js  c++  java
  • [P3390][模板] 矩阵快速幂

    题意:给定n*n的矩阵A,求A^k

    解法:矩阵快速幂;

    1.矩阵快速幂;假设有 A和 B两个矩阵,当矩阵A的列数等于矩阵B的行数时,A与B可以相乘得到矩阵 C:

    (1) 矩阵 C的行数等于矩阵 A的行数,C的列数等于 B的列数;

    (2) 乘积 C的第  行第 列的元素等于矩阵 A的第  行的元素与矩阵 B的第  列对应元素乘积之和。

    明白了这些原理之后,就可以利用快速幂的原理对矩阵进行运算了;

    附上代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    #define rg register
    using namespace std;
    const int mod = 1e9+7;
    
    ll n,k;
    ll a[101][101],b[101][101];
    ll ans[101][101];
    
    inline void matrix(){
        memcpy(b,ans,sizeof(ans));
        memset(ans,0,sizeof(ans));
        for(rg int k=1;k<=n;++k)
        for(rg int i=1;i<=n;++i)
        for(rg int j=1;j<=n;++j)
        {
            ans[i][j]=(ans[i][j]+(b[i][k]*a[k][j])%mod)%mod;
        }
    }
    
    inline void matrix_(){
        memset(b,0,sizeof(b));
        for(rg int k=1;k<=n;++k)
        for(rg int i=1;i<=n;++i)
        for(rg int j=1;j<=n;++j){
            b[i][j]=(b[i][j]+(a[i][k]*a[k][j])%mod)%mod;
        }
        memcpy(a,b,sizeof(b));
    }
    
    inline void matrix_ksm(ll bas){
        while(bas){
            if(bas&1) matrix();
            matrix_();
            bas>>=1;
        }
    }
    
    int main()
    {
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j){
            scanf("%d",&a[i][j]);
            if(i==j) ans[i][j]=1;
        }
        matrix_ksm(k);
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j) printf("%lld ",ans[i][j]);
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    AWS Redshift 采坑记
    EF Core 小工具
    Setup .net core EF
    Bat 使用MSBuild 制作发布包 (更新20180713)
    Https web Api 拉取数据踩坑记录
    C# 后台程序 通过批处理进行监控
    C#计算日期步进
    IIS 预热 (8.0及8.0以上版本)
    MSBuild 执行文档,关于使用命令行编译
    基于Bamboo的CI配置汇总(.Net Web及Api)
  • 原文地址:https://www.cnblogs.com/nnezgy/p/11512877.html
Copyright © 2011-2022 走看看