矩阵快速幂做题记录

文章讲述了矩阵乘法、矩阵快速幂算法、斐波那契数列及其相关操作(求幂、求和、平方和),以及在一个网格中的路径计数问题。

A. 矩阵乘法

时间限制:1000 ms内存限制:256 MB类型:传统评测:文本比较上传者: sysulby

提交提交记录

题目描述

给定一个  行  列的矩阵 ,与一个  行  列的矩阵 ,输出两个矩阵相乘的结果。

保证 。

输入格式

第一行有两个正整数 , 。

接下来  行,每行有  个整数,表示矩阵 。

下一行有两个正整数 , 。

接下来  行,每行有  个整数,表示矩阵 。

输出格式

输出  行,每行  个整数,用空格隔开,表示矩阵相乘的结果。

样例
样例输入复制
2 3
1 4 2
8 5 7
3 2
1 4
2 8
5 7
样例输出复制
19 50
53 121

核心思路 

A的行*B的列。

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct Matrix {
  int r, c;
  vector<vector<int> > a;

  Matrix(int r, int c): r(r), c(c) { a.assign(r, vector<int>(c)); }
  vector<int>& operator[](int i) { return a[i]; }
  const vector<int>& operator[](int i) const { return a[i]; }

  Matrix operator+(const Matrix &m) const {
    Matrix ret(r, c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < c; j++)
        ret[i][j] = a[i][j] + m[i][j];
    return ret;
  }

  Matrix operator*(const Matrix &m) const {
    Matrix ret(r, m.c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < m.c; j++)
        for (int k = 0; k < c; k++)
          ret[i][j] += a[i][k] * m[k][j];
    return ret;
  }
};
int main(){
    cin>>n>>m;
    Matrix A(n,m);
    for(int i = 0;i < n;i++){
    	for(int j = 0;j < m;j++)cin>>A[i][j];
	}
	cin>>n>>m;
	Matrix B(n,m);
	for(int i = 0;i < n;i++){
    	for(int j = 0;j < m;j++)cin>>B[i][j];
	}
	Matrix C = A*B;
	for(int i = 0;i < C.r;i++){
    	for(int j = 0;j < C.c;j++)cout<<C[i][j]<<" ";
    	cout<<endl;
	}
	return 0;
} 

B. 矩阵快速幂

时间限制:1000 ms内存限制:256 MB类型:传统评测:文本比较上传者: sysulby

提交提交记录

题目描述

给定一个  行  列的矩阵 ,求该矩阵的  次幂。

计算后的数值可能很大,输出矩阵内的每个数对  取模的结果。

输入格式

第一行有两个正整数 , 。

接下来  行,每行有  个整数,表示矩阵 。

输出格式

输出  行,每行  个整数,用空格隔开,表示矩阵  次幂的结果。

样例
样例输入复制
2 10
0 1
1 1
样例输出复制
34 55
55 89
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int mod = 1e9+7;
struct Matrix {
  int r, c;
  vector<vector<int> > a;

  Matrix(int r, int c): r(r), c(c) { a.assign(r, vector<int>(c)); }
  vector<int>& operator[](int i) { return a[i]; }
  const vector<int>& operator[](int i) const { return a[i]; }

  Matrix operator+(const Matrix &m) const {
    Matrix ret(r, c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < c; j++)
        ret[i][j] = (a[i][j] + m[i][j])%mod;
    return ret;
  }

  Matrix operator*(const Matrix &m) const {
    Matrix ret(r, m.c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < m.c; j++)
        for (int k = 0; k < c; k++){
		
          ret[i][j] = (ret[i][j] + (long long)a[i][k] * m[k][j]) % mod;
      }
    return ret;
  }
  Matrix pow(long long b) const{
  	Matrix A(r,r),ret(r,r);
  	for(int i = 0;i < r;i++){
  		ret[i][i] = 1;
  		for(int j = 0;j < c;j++)A[i][j] =(a[i][j]%mod+mod)%mod;
	}
    for(;b;A = A*A,b =  b >>1){
    	if(b & 1)ret = ret* A;
	} 
	return ret;
  	
  }
};
long long k;
int main(){
    cin>>n>>k;
    Matrix A(n,n);
    for(int i = 0;i < n;i++){
    	for(int j = 0;j < n;j++)cin>>A[i][j];
	}
	A = A.pow(k);
	for(int i = 0;i < n;i++){
		for(int j = 0;j < n;j++){
			cout<<A[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
} 

C. 斐波那契数列

时间限制:1000 ms内存限制:256 MB类型:传统评测:文本比较上传者: sysulby

提交提交记录

题目描述

已知斐波那契数列满足:

求斐波那契数列第  项。

答案可能很大,输出答案对  取模的结果。

输入格式

一行一个整数 。

输出格式

输出一行,一个整数,表示斐波那契数列第  项对  取模的结果。

样例
样例输入 1复制
100
样例输出 1复制
687995182
样例输入 2复制
1000000000
样例输出 2复制
21
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int mod = 1e9+7;
struct Matrix {
  int r, c;
  vector<vector<int> > a;

  Matrix(int r, int c): r(r), c(c) { a.assign(r, vector<int>(c)); }
  vector<int>& operator[](int i) { return a[i]; }
  const vector<int>& operator[](int i) const { return a[i]; }

  Matrix operator+(const Matrix &m) const {
    Matrix ret(r, c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < c; j++)
        ret[i][j] = (a[i][j] + m[i][j])%mod;
    return ret;
  }

  Matrix operator*(const Matrix &m) const {
    Matrix ret(r, m.c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < m.c; j++)
        for (int k = 0; k < c; k++){
		
          ret[i][j] = (ret[i][j] + (long long)a[i][k] * m[k][j]) % mod;
      }
    return ret;
  }
  Matrix pow(long long b) const{
  	Matrix A(r,r),ret(r,r);
  	for(int i = 0;i < r;i++){
  		ret[i][i] = 1;
  		for(int j = 0;j < c;j++)A[i][j] =(a[i][j]%mod+mod)%mod;
	}
    for(;b;A = A*A,b =  b >>1){
    	if(b & 1)ret = ret* A;
	} 
	return ret;
  	
  }
};
long long k;
int main(){
    cin>>k;
	Matrix A(1,2);
	A[0][0] = 1,A[0][1] = 1;
	Matrix B(2,2);
	B[0][0] = 0,B[0][1] = 1;
	B[1][0] = 1,B[1][1] = 1;
    
    A = A*B.pow(k-1);
	cout<<A[0][0]; 
	
	return 0;
} 

D. 斐波那契数列求和

时间限制:1000 ms内存限制:256 MB类型:传统评测:文本比较上传者: sysulby

提交提交记录

题目描述

已知斐波那契数列满足:

求斐波那契数列前  项的和。

答案可能很大,输出答案对  取模的结果。

输入格式

一行一个整数 。

输出格式

输出一行,一个整数,表示斐波那契数列前  项的和对  取模的结果。

样例
样例输入 1复制
100
样例输出 1复制
470199268
样例输入 2复制
1000000000
样例输出 2复制
7
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int mod = 1e9+7;
struct Matrix {
  int r, c;
  vector<vector<int> > a;

  Matrix(int r, int c): r(r), c(c) { a.assign(r, vector<int>(c)); }
  vector<int>& operator[](int i) { return a[i]; }
  const vector<int>& operator[](int i) const { return a[i]; }

  Matrix operator+(const Matrix &m) const {
    Matrix ret(r, c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < c; j++)
        ret[i][j] = (a[i][j] + m[i][j])%mod;
    return ret;
  }

  Matrix operator*(const Matrix &m) const {
    Matrix ret(r, m.c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < m.c; j++)
        for (int k = 0; k < c; k++){
		
          ret[i][j] = (ret[i][j] + (long long)a[i][k] * m[k][j]) % mod;
      }
    return ret;
  }
  Matrix pow(long long b) const{
  	Matrix A(r,r),ret(r,r);
  	for(int i = 0;i < r;i++){
  		ret[i][i] = 1;
  		for(int j = 0;j < c;j++)A[i][j] =(a[i][j]%mod+mod)%mod;
	}
    for(;b;A = A*A,b =  b >>1){
    	if(b & 1)ret = ret* A;
	} 
	return ret;
  	
  }
};
long long k;
int main(){
    cin>>k;
	Matrix A(1,3);
	A[0][0] = 1,A[0][1] = 1,A[0][2] = 0;
	Matrix B(3,3);
	B[0][0] = 0,B[0][1] = 1,B[0][2] = 1;
	B[1][0] = 1,B[1][1] = 1,B[1][2] = 0;
    B[2][0] = 0,B[2][1] = 0,B[2][2] = 1;
    A = A*B.pow(k);
	cout<<A[0][2]; 
	
	return 0;
} 

E. 斐波那契数列平方和

时间限制:1000 ms内存限制:256 MB类型:传统评测:文本比较上传者: sysulby

提交提交记录

题目描述

已知斐波那契数列满足:

求斐波那契数列前  项的平方和。

答案可能很大,输出答案对  取模的结果。

输入格式

一行一个整数 。

输出格式

输出一行,一个整数,表示斐波那契数列前  项的平方和对  取模的结果。

样例
样例输入 1复制
100
样例输出 1复制
245606600
样例输入 2复制
1000000000
样例输出 2复制
999999734
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int mod = 1e9+7;
struct Matrix {
  int r, c;
  vector<vector<int> > a;

  Matrix(int r, int c): r(r), c(c) { a.assign(r, vector<int>(c)); }
  vector<int>& operator[](int i) { return a[i]; }
  const vector<int>& operator[](int i) const { return a[i]; }

  Matrix operator+(const Matrix &m) const {
    Matrix ret(r, c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < c; j++)
        ret[i][j] = (a[i][j] + m[i][j])%mod;
    return ret;
  }

  Matrix operator*(const Matrix &m) const {
    Matrix ret(r, m.c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < m.c; j++)
        for (int k = 0; k < c; k++){
		
          ret[i][j] = (ret[i][j] + (long long)a[i][k] * m[k][j]) % mod;
      }
    return ret;
  }
  Matrix pow(long long b) const{
  	Matrix A(r,r),ret(r,r);
  	for(int i = 0;i < r;i++){
  		ret[i][i] = 1;
  		for(int j = 0;j < c;j++)A[i][j] =(a[i][j]%mod+mod)%mod;
	}
    for(;b;A = A*A,b =  b >>1){
    	if(b & 1)ret = ret* A;
	} 
	return ret;
  	
  }
};
long long k;
int main(){
    cin>>k;
	Matrix A(1,4);
	A[0][0] = 1,A[0][1] = 1,A[0][2] = 1,A[0][3] = 0;
	Matrix B(4,4);
	B[0][0] = 0,B[0][1] = 1,B[0][2] = 0,B[0][3] = 1;
	B[1][0] = 1,B[1][1] = 1,B[1][2] = 1,B[1][3] = 0;
    B[2][0] = 0,B[2][1] = 2,B[2][2] = 1,B[2][3] = 0;
    B[3][0] = 0,B[3][1] = 0,B[3][2] = 0,B[3][3] = 1;
    A = A*B.pow(k);
	cout<<A[0][3]; 
	
	return 0;
} 

 

F. 路径计数

时间限制:1000 ms内存限制:256 MB类型:传统评测:文本比较上传者: sysulby

提交提交记录

题目描述

已知有一个  行  列的网格,起始在。

若当前位于第  行第  列,在不移动出网格的情况下,允许:

  • 向左下角移动一步,走到第  行,第  列
  • 向下移动一步,走到第  行,第  列
  • 向右下角移动一步,走到第  行,第  列

计算从左上角(第  行的第  列)走到右下角(第  行第  列)的方案数。

答案可能很大,输出答案对  取模的结果。

输入格式

一行两个整数 , 。

输出格式

输出一行,一个整数,表示方案数对  取模的结果。

样例
样例输入 1复制
5 3
样例输出 1复制
8
样例输入 2复制
1000000000 100
样例输出 2复制
408053181
#include<bits/stdc++.h>
using namespace std;
long long n,m;
const int mod = 1e9+7;
struct Matrix {
  int r, c;
  vector<vector<int> > a;

  Matrix(int r, int c): r(r), c(c) { a.assign(r, vector<int>(c)); }
  vector<int>& operator[](int i) { return a[i]; }
  const vector<int>& operator[](int i) const { return a[i]; }

  Matrix operator+(const Matrix &m) const {
    Matrix ret(r, c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < c; j++)
        ret[i][j] = (a[i][j] + m[i][j])%mod;
    return ret;
  }

  Matrix operator*(const Matrix &m) const {
    Matrix ret(r, m.c);
    for (int i = 0; i < r; i++)
      for (int j = 0; j < m.c; j++)
        for (int k = 0; k < c; k++){
		
          ret[i][j] = (ret[i][j] + (long long)a[i][k] * m[k][j]) % mod;
      }
    return ret;
  }
  Matrix pow(long long b) const{
  	Matrix A(r,r),ret(r,r);
  	for(int i = 0;i < r;i++){
  		ret[i][i] = 1;
  		for(int j = 0;j < c;j++)A[i][j] =(a[i][j]%mod+mod)%mod;
	}
    for(;b;A = A*A,b =  b >>1){
    	if(b & 1)ret = ret* A;
	} 
	return ret;
  	
  }
};
long long k;
int main(){
    cin>>n>>m;
	Matrix A(1,m);
	A[0][0] = 1;
	Matrix B(m,m);
	for(int i = 0;i < m;i++){
		for(int j = 0;j < m;j++){
			if(i == j||i == j+1||i == j-1)B[i][j] = 1;
		}
	}
    A = A*B.pow(n-1);
	cout<<A[0][m-1]; 
	
	return 0;
} 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值