您的位置:首页 > 其它

POJ 3233 Matrix Power Series

2017-08-19 17:15 399 查看
题意是这样的,给定一个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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: