P3390 【模板】矩阵快速幂(Java&C++)

矩阵快速幂

题目链接: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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值