1. 程式人生 > >[模板] 矩陣快速冪

[模板] 矩陣快速冪

sin temp 想是 read mat class () || col

矩陣快速冪是一個快速冪的延伸,但實際上區別不大,主要思想是一樣的.

題幹:

題目背景

矩陣快速冪
題目描述

給定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<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define
clean(a) memset(a,0,sizeof(a)) #define mp make_pair #define pr pair<int,int> const int INF = 1e9 + 7; typedef long long ll; typedef double db; #define mod 1000000007 template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < 0 || c > 9)
if(c == -) op = 1; x = c - 0; while(c = getchar(), c >= 0 && c <= 9) x = x * 10 + c - 0; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar(-), x = -x; if(x >= 10) write(x / 10); putchar(0 + x % 10); } ll n,k; struct node { ll m[120][120]; }; node mi() { node k; duke(i,1,n) { k.m[i][i] = 1; } return k; } node mul(node x,node y) { node k; duke(i,1,n) duke(j,1,n) k.m[i][j] = 0; duke(i,1,n) { duke(j,1,n) { duke(z,1,n) { k.m[i][j] = (k.m[i][j] + x.m[i][z] * y.m[z][j] % mod) % mod; } } } return k; } node ksm(node a,ll b) { node tmp = mi(); while(b) { if(b & 1) tmp = mul(tmp,a); a = mul(a,a); b >>= 1; } return tmp; } void output(node x) { duke(i,1,n) { duke(j,1,n) { printf("%lld ",x.m[i][j]); } puts(""); } return; } int main() { read(n);read(k); node a; duke(i,1,n) { duke(j,1,n) { read(a.m[i][j]); } } node res = ksm(a,k); output(res); return 0; } /* 2 1 1 1 1 1 */

[模板] 矩陣快速冪