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

被折叠的 条评论
为什么被折叠?



