POJ 3233Matrix Power Series

来源:互联网 发布:php网站数据库在哪里 编辑:程序博客网 时间:2024/06/09 04:38

题意是这样的,给定一个n*n的矩阵,求这个矩阵一次方到m次方的和,模mod。

这个时候就要发挥数列的知识了,S(n)=A的1次方+A的2次方+...+A的n次方,将后面n-1项提出一个A,即可转换

为S(n)=A+S(n-1).这就有了矩阵乘法的基础了,下面通过矩阵套矩阵,即数组的左半边为第一个矩阵,右半边为

第二个矩阵,以此类推。

A 0

S(n-1) E * A E = S(n) E

通过如上构造矩阵,进行矩阵快速幂操作,输出ans的左半个矩阵即为答案了。

下附AC代码。

#include<iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#define maxn 105 using namespace std;struct Matrix{int n,m;long long val[maxn][maxn];};long long mod;Matrix quickmul(Matrix mat1,Matrix mat2){Matrix ans;ans.n=mat1.n;ans.m=mat2.m;memset(ans.val,0,sizeof(ans.val));for(int i=1;i<=mat1.n;i++){for(int j=1;j<=mat2.m;j++){for(int k=1;k<=mat1.m;k++){ans.val[i][j]+=mat1.val[i][k]*mat2.val[k][j];ans.val[i][j]%=mod;}}}return ans;}Matrix quickpow(Matrix n,unsigned long long k){bool flag=true;Matrix ans;while(k){if(k&1){if(flag){flag=false;ans=n;}else {ans=quickmul(ans,n);}}n=quickmul(n,n);k=k>>1;}return ans;}Matrix a,b;int n;long long k;long long a1[maxn][maxn];long long temp[maxn][maxn];void out(Matrix now){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)cout<<now.val[i][j]<<' ';cout<<endl;}exit(0);}int main(){cin>>n>>k>>mod;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)cin>>a1[i][j];if(k==1){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)cout<<a1[i][j]<<' ';cout<<endl;}exit(0);}a.n=n;a.m=2*n;b.n=2*n;b.m=2*n;memset(b.val,0,sizeof(b.val));for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){a.val[i][j]=a1[i][j];a.val[i][j+n]=a1[i][j];b.val[i][j]=a1[i][j];}for(int i=1;i<=n;i++)temp[i][i]=1;for(int i=n+1;i<=2*n;i++)for(int j=1;j<=n;j++){b.val[i][j]=temp[i-n][j];b.val[i][j+n]=temp[i-n][j];}Matrix ans=quickmul(a,quickpow(b,k-1));out(ans);}

原创粉丝点击