原题链接:http://poj.org/problem?id=3233
这一题是求S=A+A^2+....+A^K的和矩阵(二分再二分)
贴我的矩阵快速幂(二分思想)模板链接:http://blog.csdn.net/x_xueting/article/details/77507566
然后就是求和的二分
举个例子当k=6时 A+A^2+A^3+A^4+A^5+A^6=(A^1+A^2+A^3)+(A^1+A^2+A^3)*A^3
K=5时 A+A^2+A^3+A^4+A^5=(A+A^2)+(A+A^2)*A^3+A^3
这就是二分的思想
当k为偶数时: A^1+A^2+...+A^K=(A^1+A^2+...+A^(K/2))+(A^1+A^2+...+A^(K/2))*A^(K/2)
F(k)=F(k/2)+F(k/2)*A^(K/2)
当k为奇数时:A^1+A^2+...+A^K=(A^1+A^2+...+A^(K/2))+(A^1+A^2+...+A^(K/2))*A^(K/2+1)+A^(K/2+1)
F(k)=F(k/2)+F(k/2)*A^(k/2+1)+A^(k/2+1)(利用递归去求)
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long int
using namespace std;
int n;
ll m,k;
typedef struct mar
{
ll matrix[31][31];
} Mar;
void print(Mar a)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
cout<<a.matrix[i][j]%m<<" ";
cout<<endl;
}
}
Mar mul(Mar a,Mar b)
{
Mar temp;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
temp.matrix[i][j]=0;
for(int t=0; t<n; t++)
{
temp.matrix[i][j]+=(a.matrix[i][t]*b.matrix[t][j])%m;
}
temp.matrix[i][j]%=m;
}
}
return temp;
}
Mar power(Mar mar,ll r)
{
Mar mt;
memset(mt.matrix,0,sizeof(mt.matrix));
for(int i=0; i<n; i++)
mt.matrix[i][i]=1;
while(r)
{
if(r&1)
mt=mul(mar,mt);
mar=mul(mar,mar);
r=r/2;
}
return mt;
}
Mar Add(Mar a,Mar b)
{
Mar temp;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
temp.matrix[i][j]=a.matrix[i][j]+b.matrix[i][j];
temp.matrix[i][j]%=m;
}
}
return temp;
}
Mar c;
Mar F(ll s)
{
if(s==1)
return c;
else
{
Mar res=F(s/2);
if(s%2)
{
Mar cur=power(c,s/2+1);
res=Add(Add(res,cur),mul(cur,res));
return res;
}
else
{
Mar cur=power(c,s/2);
res=Add(res,mul(cur,res));
return res;
}
}
}
int main()
{
while(cin>>n>>k>>m)
{
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
cin>>c.matrix[i][j];
c=F(k);
print(c);
}
return 0;
}