矩阵快速幂(模板)

题目背景

矩阵快速幂

题目描述

给定 n×nn imes nn×n 的矩阵 AAA,求 AkA^kAk。

输入格式

第一行两个整数 n,kn,kn,k 接下来 nnn 行,每行 nnn 个整数,第 iii 行的第 jjj 的数表示 Ai,jA_{i,j}Ai,j

输出格式

输出 AkA^kAk

nnn 行,每行 nnn 个数,第 iii 行第 jjj 个数表示 (Ak)i,j(A^k)_{i,j}(Ak)i,j,每个元素对 109+710^9+7109+7 取模。

输入输出样例

输入 #1
2 1
1 1
1 1
输出 #1
1 1
1 1

说明/提示

【数据范围】
对于 100%100\%100% 的数据:1≤n≤1001le n le 1001n100,0≤k≤10120 le k le 10^{12}0k1012, ∣Ai,j∣≤1000|A_{i,j}| le 1000 Ai,j1000

https://www.luogu.com.cn/problem/P3390
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map> 
#include<bits/stdc++.h> 
#include <math.h>
using namespace std;
typedef  long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=5e5+10;
const int mod=1e9+7; 
ll n,k;
struct node{
    ll a[110][110];
}p,pp;//p代表读入矩阵,pp代表输出矩阵 
node qu(node x,node y){//返回一个矩阵 
    node box;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            box.a[i][j]=0; 
        } 
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                box.a[i][j]=(box.a[i][j]+(x.a[i][k]*y.a[k][j])%mod)%mod;
            }
        }
    }
    return box;
}
node ju_pow(ll k){
    node ans;
    for(int i=1;i<=n;i++){
        ans.a[i][i]=1;
    }
    while(k){
        if(k%2){
            ans=qu(ans,p);
        }
        p=qu(p,p);
        k/=2;
    }
    return ans; 
}
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%lld",&p.a[i][j]);
        }
    }
    pp=ju_pow(k);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            printf("%lld ",pp.a[i][j]);
        }
        cout<<endl;
    }
}

模板快

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int N = 7;
const LL mod = 2147493647;
LL n, m;
struct mac {
    LL c[N][N];
    void reset() {
        memset(c, 0, sizeof(c));
        for (int i = 0; i <= 6; i++)
            c[i][i] = 1;
    }
};
mac multi(mac a, mac b)
{
    mac ans;
    for (int i = 0; i <= 6; i++)
        for (int j = 0; j <= 6; j++) {
            ans.c[i][j] = 0;
            for (int k = 0; k <= 6; k++) {
                ans.c[i][j] += (a.c[i][k] * b.c[k][j]) % mod;
                ans.c[i][j] %= mod;
            }
        }
    return ans;
}
mac Pow(mac a, LL b)
{
    mac ans; ans.reset();
    while (b) {
        if (b & 1)
            ans = multi(ans, a);
        a = multi(a, a);
        b >>= 1;
    }
    return ans;
}
int main()
{
    int t; 
    LL n,kk,ll;
    mac a={
        1,2,1,0,0,0,0,
        1,0,0,0,0,0,0,
        0,0,1,4,6,4,1,
        0,0,0,1,3,3,1,
        0,0,0,0,1,2,1,
        0,0,0,0,0,1,1,
        0,0,0,0,0,0,1
    };
    cin>>t;
    while(t--){
        cin>>n>>kk>>ll; 
        if(n==1){
            printf("%lld
",kk);
        }
        else if(n==2){
            printf("%lld
",ll);
        }
        else{
            mac res=Pow(a,n-2);
            LL ans=(ll*res.c[0][0]%mod+kk*res.c[0][1]%mod+81*res.c[0][2]%mod+27*res.c[0][3]%mod+9*res.c[0][4]%mod+3*res.c[0][5]%mod+res.c[0][6]%mod)%mod;
            printf("%lld
",ans%mod);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lipu123/p/12563308.html