矩阵快速幂
最近学数学学的比较多,矩阵快速幂应该算数学吧。
题目链接
题目大意:
给定\(n\),\(k\),然后给定\(n \times n\)的矩阵A,求\(A^k\)
数据范围:
\(1\le n \le 100,0 \le q \le 10^12,\vert A_{i,j} \vert \le 1000\)
做法就和快速幂没什么区别,把\(k\)进行二进制拆分,然后快速幂模板
我\(k\)开了long long,读入用的%d,一直没看出来,拖了好久[貌似是重构之后发现的]
看到\(k\)的范围,请大家一定记住:
\(1\) \(0\) 年 \(O\) \(I\) 一 场 空 , 不 开 \(l\) \(o\) \(n\) \(g\) \(l\) \(o\) \(n\) \(g\) 见 祖 宗 。
long long re=1;
for(;power;power>>=1,base=base*base){
if(power&1)re=re*base;//for循环甚至可以压到一行
}
return re;
只不过这里的\(base\)乘不再是一个数,而是一个矩阵,\(mat\)也一样,需要注意的是,在矩阵里\(1\)代表的是单位矩阵,所以注意返回值要初始化成单位矩阵[对角线都是\(1\)].剩下的矩阵乘法就行了
以下是模板
struct Matrix{//结构体
ll a[N][N];//ll就是long long
Matrix(){
memset(a,0,sizeof(a));//一旦定义,初始化为这样
}
void scan(){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
in(a[i][j]);//读入矩阵,n开的全局变量,不需要矩阵里自己存
}
void init(){
for(int i=1;i<=n;i++)
a[i][i]=1;//init有初始化的意思,这里是单位矩阵初始化
}
void print(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
out(a[i][j]);//输出
putchar(10);//10在ASCII码中是换行,32是空格
}
}
Matrix operator * (const Matrix &b)const{//重载乘法为矩阵乘法
Matrix ret;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int u=1;u<=n;u++)
ret.a[i][j]=(ret.a[i][j]+(a[i][u]*b.a[u][j])%md)%md;//矩阵乘的定义,i行j列的数,是前一个矩阵第i行乘后一个第j列
return ret;
}
}mat,base;
主函数:
int main(){
in(n),in(k);
base.scan();mat.init();//mat就是ans,base就是底数
MQP(k);//Matrix Quick Power 矩阵 快速 乘方
mat.print();//输出
return 0;
}
我不想就这样沦陷,迷失在黑夜,我将燃烧这生命,就算再壮烈。