1. 程式人生 > >【模板】矩陣快速冪

【模板】矩陣快速冪

oid -c algorithm adg col emc print cstring -o

題目背景

矩陣快速冪

題目描述

給定n*n的矩陣A,求A^k

輸入輸出格式

輸入格式:

第一行,n,k

第2至n+1行,每行n個數,第i+1行第j個數表示矩陣第i行第j列的元素

輸出格式:

輸出A^k

共n行,每行n個數,第i行第j個數表示矩陣第i行第j列的元素,每個元素模10^9+7

輸入輸出樣例

輸入樣例#1:
2 1
1 1
1 1
輸出樣例#1:
1 1
1 1

說明

n<=100, k<=10^12, |矩陣元素|<=1000 算法:矩陣快速冪

#include <cstdio>
#include <cmath>
#include 
<cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int mod = 1e9 + 7; ll n, k; ll ans[110][110], a[110][110], b[110][110]; void mul2() { memset(b, 0, sizeof(b)); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++) b[i][j] = (b[i][j] + ans[i][k] * a[k][j] % mod) % mod; memcpy(ans, b, sizeof(b)); } void mul1() { memset(b, 0, sizeof(b)); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) b[i][j]
= (b[i][j] + a[i][k] * a[k][j] % mod) % mod; memcpy(a, b, sizeof(b)); } void qpow(ll b) { for (int i = 1; i <= n; i++) ans[i][i] = 1; while (b) { if (b & 1) mul2(); mul1(); b >>= 1; } } int main() { scanf("%lld%lld", &n, &k); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) scanf("%lld", &a[i][j]); qpow(k); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) printf("%lld ", ans[i][j]); printf("\n"); } return 0; }

【模板】矩陣快速冪