矩阵快速幂
题目链接:https://www.luogu.com.cn/problem/P3390
题目描述
给定 n×n 的矩阵 A,求 A^k。
输入格式
第一行两个整数 n,k接下来 n 行,每行 n 个整数,第 i 行的第 j 的数表示 A
i,j。
输出格式
输出 A^k
共 n 行,每行 n 个数,第 i 行第 j 个数表示 (A^k) ,每个元素对 10^9+7取模。
输入输出样例
输入 #1
2 1
1 1
1 1
输出 #1
1 1
1 1
说明/提示
【数据范围】
对于 100%100% 的数据:1≤n≤100,0≤k≤10^12 ∣A i,j∣≤1000
解题思路:
矩阵乘法+快速幂
矩阵乘法模板
C++
matrix mul(matrix a,matrix b){
matrix t;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
t.m[i][j]=0;
for(int k=1;k<=n;k++)
t.m[i][j]=(t.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
}
return t;
}
Java
private static long[][] mul(long[][] a, long[][] b) {
long[][] c = new long[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
c[i][j] = (c[i][j] + (a[i][k] * b[k][j])) % mod;
}
}
}
return c;
}
普通快速幂模板
C++
ll ksm(ll a,ll b,ll mod){
ll ans = 1;
while(b){
if(b&1){
ans=ans*a%mod;
b--;
}
b/=2;
a=a*a%mod;
}
return ans;
}
Java
public static int ksm(long a, long b, int k) {
if (a == 0)
return 0;
int ans = 1;
if (b == 0)
return 1 % k;
while (b != 0) {
if ((b & 1) != 0) {
ans = (int) (ans * a % k); // 防止溢出
}
b >>= 1; // 去掉最低位
a = a * a % k;
}
return ans;
}
矩阵快速幂模板
C++
matrix ksm(matrix a, ll k){
matrix ans=a,b=a;k--;
while(k>0){
if(k&1)
ans=mul(b,ans);
b=mul(b,b);k/=2;
}
return ans;
}
Java
private static void ksm(long[][] a, long m) {
long[][] ans = new long[n + 1][n + 1];
for (int i = 1; i <= n; i++)
ans[i][i] = 1;
while (m != 0) {
if ((m & 1) != 0) {
ans = mul(ans, a);m--;
} else {
a = mul(a, a);m /= 2;
}
}
代码如下:
Java
import java.util.Scanner;
public class Main {
static int n;
static long mod = 1000000007;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
long m = sc.nextLong();
long[][] a = new long[n + 1][n + 1];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a[i][j] = sc.nextLong() % mod;
ksm(a, m);
}
//快速幂
private static void ksm(long[][] a, long m) {
long[][] ans = new long[n + 1][n + 1];
for (int i = 1; i <= n; i++)
ans[i][i] = 1;
while (m != 0) {
if ((m & 1) != 0) {
ans = mul(ans, a);m--;
} else {
a = mul(a, a);m /= 2;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
System.out.print(ans[i][j] + " ");
}
System.out.println();
}
}
//矩阵乘法
private static long[][] mul(long[][] a, long[][] b) {
long[][] c = new long[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
c[i][j] = (c[i][j] + (a[i][k] * b[k][j])) % mod;
}
}
}
return c;
}
}
C++
#include<iostream>
using namespace std;
#define ll long long
const int mod = 1000000007;
ll n,k;
struct matrix{
ll m[105][105];
}a;
//矩阵乘法
matrix mul(matrix a,matrix b){
matrix t;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
t.m[i][j]=0;
for(int k=1;k<=n;k++)
t.m[i][j]=(t.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
}
return t;
}
//快速幂
matrix ksm(matrix a, ll k){
matrix ans=a,b=a;k--;
while(k>0){
if(k&1)
ans=mul(b,ans);
b=mul(b,b);k/=2;
}
return ans;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a.m[i][j];
a=ksm(a,k);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
cout<<a.m[i][j]<<" ";
cout<<endl;
}
return 0;
}