# poj 3233 --- Matrix Power Series (二分,矩阵)

Matrix Power Series
 Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 9393 Accepted: 4018

Description

Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

Input

The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.

Output

Output the elements of S modulo m in the same way as A is given.

Sample Input

2 2 4
0 1
1 1

Sample Output

1 2
2 3

Source

POJ Monthly--2007.06.03, Huang, Jinsong

Sk = A + A2 + A3 + … + Ak

=(1+Ak/2)*(A + A2 + A3 + … + Ak/2  )+{Ak}

=(1+Ak/2)*(Sk/2 )+{Ak}// k为偶数时无 {Ak}

A  可用二分迭代求出

//800MS
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int m,n,K;
int a[30][30];
class Matrix
{
public:
int num[30][30];
Matrix(bool is=true)		//初始化
{
memset(num,0,sizeof(num));
if(is)
for(int i=0;i<n;i++)
num[i][i]=1;
}
void print()				//输出函数
{
for(int i=0;i<n;++i)
{
printf("%d",num[i][0]);
for(int j=1;j<n;++j)
printf(" %d",num[i][j]);
printf("\n");
}
}
//重载乘法运算
friend Matrix& operator *(const Matrix& max1,const Matrix& max2)
{
Matrix tmp(false);				//注意这里是false,即初始化的矩阵不是单位矩阵I
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
{
for(int k=0;k<n;++k)
tmp.num[i][j]+=(max1.num[i][k]*max2.num[k][j])%m;
tmp.num[i][j]%=m;
}
return tmp;
}
//重载+=运算
Matrix& operator +=(const Matrix& max)
{
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
num[i][j]=(num[i][j]+max.num[i][j])%m;

return *this;
}
}ans;
Matrix mul(Matrix A,int k)		//求A^K
{
if(k==1)
return A;
Matrix tmp ;
while(k)
{
if(k&1)
tmp = tmp * A;
k>>=1;
A = A*A;
}
return tmp;
}
Matrix S(Matrix A,int k)		//求 S[k]
{
if(k==1)
return A;

Matrix tmp ;
tmp += mul(A,k>>1);			//求 (I + A^(k/2) )
tmp = tmp*S(A,k>>1);		//求 (I + A^(k/2) )*S[k/2]
if(k&1)						//判断时候要加上 A^k
tmp+= mul(A,k);			//S[k] = (I+A^(k/2)) * S[k/2] + {A^k}
return tmp;
}

int main()
{
int i,j,k;
scanf("%d %d %d",&n,&K,&m);
for( i=0;i<n;++i)
for( j=0;j<n;++j)
scanf("%d",&ans.num[i][j]);
ans = S(ans,K);
ans.print();

return 0;
}

//266MS
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int m,n,K;
int a[30][30];
class Matrix
{
public:
int num[61][61];
Matrix()
{
memset(num,0,sizeof(num));
}
void print()
{
for(int i=0;i<n;++i)
{
printf("%d",num[i][0]);
for(int j=1;j<n;++j)
printf(" %d",num[i][j]);
printf("\n");
}
printf("\n");
}
friend Matrix& operator *(Matrix max1,Matrix max2);
};
Matrix& operator *(Matrix max1,Matrix max2)
{
Matrix tmp;
for(int i=0;i<2*n;++i)
for(int j=0;j<2*n;++j)
{
for(int k=0;k<2*n;++k)
tmp.num[i][j]+=(max1.num[i][k]*max2.num[k][j])%m;
tmp.num[i][j]%=m;
}
return tmp;
}
int main()
{
scanf("%d %d %d",&n,&K,&m);
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
scanf("%d",&a[i][j]);
Matrix b,c;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
c.num[i+n][j+n]=b.num[i][j+n]=a[i][j];
for(int k=0;k<2;++k)
for(int i=0;i<n;++i)
c.num[i+k*n][i]=1;
while(K)
{
if(K&1)
b=b*c;
K>>=1;
c=c*c;
}
b.print();
return 0;
}

#include<cstdio>
#include<cstring>
using namespace std;
int i,j,k,n,l,m,r;
bool s[32];
struct matrix
{
int a[30][30];
void pr()
{
for(i=0; i<n;printf("%d/n",a[i++][j]))
for(j=0;j<n-1;++j)printf("%d ",a[i][j]);
}
matrix& operator+=(const matrix&x)
{
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j)
if(x.a[i][j])
{
a[i][j]+=x.a[i][j];
if(a[i][j]>=m)a[i][j]%=m;
}
return *this;
}
matrix& operator*=(const matrix&x)
{
matrix t;
int i,j,k;
for(i=0; i<n; ++i)
for(j=0; j<n; ++j)t.a[i][j]=0;
for(i=0; i<n; ++i)
for(k=0; k<n; ++k)
if(a[i][k])
for(j=0; j<n; ++j)
{
t.a[i][j]+=a[i][k]*x.a[k][j];
if(t.a[i][j]>=m)t.a[i][j]%=m;
}
return memcpy(a,t.a,sizeof(a)),*this;
}
} t,a,unit,ans,exp;
int& fun(int &a)
{
return a;
}
int main()
{
for(scanf("%d%d%d",&n,&l,&m),i=0; i<30; ++i)unit.a[i][i]=1;
for(i=0; i<n; ++i)
for(j=0; j<n; ++j)
scanf("%d",a.a[i]+j);
for(r=-1;l;l>>=1)s[++r]=l&1;
for(ans=exp=a; --r>=0; exp*=exp,s[r]?exp*=a:exp)
t=exp,s[r]?ans*=(t*=a)+=unit,ans+=(t=exp)*=a:ans*=t+=unit;
ans.pr();
return 0;
}

#### 矩阵十大经典题目之三-POJ-3233-Matrix Power Series-两次二分

2014-03-11 16:48:02

#### POJ3233 Matrix Power Series 矩阵快速幂+二分求和

2015-06-09 16:10:29

#### POJ 3233 Matrix Power Series (矩阵快速幂＋二分)

2015-02-18 20:52:37

#### POJ 3233-Matrix Power Series( S = A + A^2 + A^3 + … + A^k 矩阵快速幂取模)

2016-08-03 13:42:13

#### POJ 2593 Max Sequence

2017-04-15 22:39:37

#### POJ Matrix Power Series （矩阵快速幂+二分）

2015-02-04 14:31:11

#### poj3233 Matrix Power Series(矩阵快速幂)

2015-04-08 17:12:53

#### 南阳acm士兵杀敌系列

2017-07-27 22:16:20

#### acm-Matrix Power Series

2013-11-12 16:44:46

#### ???题目3 : Matrix

2017-09-26 19:41:34