uva11149power of matrix二分
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87585#problem/B
题意:A+A^2+A^3+……+A^k,A为矩阵,首先输入A的介数n和次数k,再输入A,要求将结果输出。
思路:
当n为偶数时,
f(n)=f(n/2)+f(n/2)*A^(n/2)=f(n/2)(E+A^(n/2)),
当n为奇数时,
f(n)=f(n/2)+f(n/2)*A^(n/2)+A^n=f(n/2)(E+A^(n/2))+A^n。
(二分法)
一开始看到输出中说因为数据过大要输出最后一位数据,认为是数组的最后一个数,但是看例题又不是那样,后来看题解才明白是每个数组元素的最后一位。
在所有可以%10的地方%10。
#include<iostream> using namespace std; typedef long long ll; struct Matrix { ll v[41][41]; }; Matrix m; Matrix k(int n) { Matrix a; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { a.v[i][j]=0; } } return a; }//将给定介数的矩阵化为零矩阵 Matrix E(int n) { Matrix a=k(n); for(int i=0;i<n;i++) { a.v[i][i]=1; } return a; }//单位矩阵 Matrix sum(Matrix a,Matrix b,int n) { Matrix c; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { c.v[i][j]=a.v[i][j]+b.v[i][j]; c.v[i][j]%=10; } } return c; }//矩阵加法 Matrix mul(Matrix a,Matrix b,int n) { Matrix c; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { c.v[i][j]=0; for(int l=0;l<n;l++) { c.v[i][j]+=a.v[i][l]*b.v[l][j]; c.v[i][j]%=10; } } } return c; }//矩阵乘法 Matrix pow(Matrix a,int k,int n) { if(k==1)return a; Matrix b=pow(a,k>>1,n); if(k%2)return mul(mul(b,b,n),m,n); else return mul(b,b,n); }//矩阵快速幂 Matrix qpow(Matrix a,int k,int n) { if(k==1)return a; Matrix b=qpow(a,k/2,n); Matrix c=sum(E(n),pow(a,k/2,n),n); if(k%2)return sum(mul(b,c,n),pow(a,k,n),n); else return mul(b,c,n); }//矩阵二分法快速求和 void input(int n) { for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cin>>m.v[i][j]; m.v[i][j]%=10; } } }//输入A void show(Matrix a,int n) { for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cout<<a.v[i][j]; if(j==n-1)cout<<endl; else cout<<" "; } } cout<<endl; }//输出结果 int main() { int n,k; while(cin>>n>>k&&n)//当n是0时结束程序,案例中给出的是0 0,故while(cin>>n>>k&&n) { input(n); Matrix e=m; Matrix ans=qpow(e,k,n); show(ans,n); } return 0; }