题目背景
矩阵快速幂
题目描述
给定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
输入输出样例
题解:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <exception>
#include <typeinfo>
using namespace std;
using int_t = unsigned long long int;
const int_t mod = (int_t) 1e9 + 7;
//Matrix的前置声明,用于下面两个函数
template <typename ValType>
class Matrix;
//友元函数的声明
//模板类的友元函数必须显式的写明模板
template <typename T>
ostream& operator<<(ostream & os, const Matrix<T> & mat);
template <typename T>
istream& operator>>(istream & os, const Matrix<T> & mat);
//Matrix类,表示一个矩阵
template <typename ValType>
class Matrix {
private:
ValType* data;
int_t row;
int_t col;
int_t size;
int_t num;
public:
//析构函数,释放内存
~Matrix() {
delete[] data;
}
//拷贝构造函数
Matrix(const Matrix<ValType>& other) :
row(other.row), col(other.col), size(other.size), num(other.num) {
data = new ValType[other.num];
memcpy(data, other.data, other.size);
}
//默认构造函数,动态分配内存
Matrix(int_t r, int_t c) :
row(r), col(c) {
this->row = r;
this->col = c;
num = (row + 1)*(col + 1);
data = new ValType[num];
size = sizeof (ValType) * num;
memset(data, 0, size);
}
//访问矩阵的某个元素
ValType& at(int_t r, int_t c) {
return data[c + r * col];
}
//重载的*运算符,矩阵无法相乘时会抛出异常
Matrix<ValType> operator*(Matrix<ValType>& mat) throw (const char*) {
if (this->col != mat.row) throw "Column number of matrix1 doesn't equals that in matrix2";
Matrix<ValType> result(this->row, mat.col);
for (int_t i = 1; i <= this->row; i++) {
for (int_t j = 1; j <= mat.col; j++) {
int_t sum = 0;
for (int_t x = 1; x <= this->col; x++) {
sum = (sum % mod + at(i, x) % mod * mat.at(x, j) % mod) % mod;
}
result.at(i, j) += sum % mod;
}
}
return result;
}
int_t getCol() const {
return col;
}
int_t getRow() const {
return row;
}
//赋值构造函数
Matrix<ValType> & operator=(const Matrix<ValType> & other) {
this->col = other.col;
this->num = other.num;
this->row = other.row;
this->size = other.size;
this->data = new ValType[num];
memcpy(data, other.data, size);
}
//友元,函数名后必须写<>以告诉编译器这个友元使用了模板,如果不能从参数中推断模板类型那么还必须在<>内写上模板类型
//程序写完以后我才发现,这两个函数其实根本不用友元..
friend ostream& operator<< <>(ostream & os, const Matrix<ValType> & mat);
friend istream& operator>> <>(istream & os, const Matrix<ValType> & mat);
};
//友元函数的实现
template <typename ValType>
ostream & operator<<(ostream & os, Matrix<ValType> & mat) {
for (int_t i = 1; i <= mat.getRow(); i++) {
for (int_t j = 1; j <= mat.getCol(); j++) {
os << mat.at(i, j) % mod << " ";
}
os << endl;
}
return os;
}
template <typename ValType>
istream & operator>>(istream & is, Matrix<ValType> & mat) {
for (int_t i = 1; i <= mat.getRow(); i++) {
for (int_t j = 1; j <= mat.getCol(); j++) {
is >> mat.at(i, j);
mat.at(i, j) %= mod;
}
}
return is;
}
using MatType = Matrix<int_t>;
int main() {
int_t n, index;
cin >> n>>index;
MatType mat(n, n);
cin>>mat;
MatType result = mat;
//普通的快速幂
//快速幂卡了很长时间,以前写的一直结果错误,然而这样写就对了,具体参考我的提交记录
for (index--; index; index>>=1,mat = mat * mat) {
if (index & 1) result = result * mat;
}
cout << result;
return 0;
}