# 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;
}

• 本文已收录于以下专栏：

## poj3233 - Matrix Power Series

• wangjian8006
• 2012年08月15日 14:14
• 4485

## poj 3233 Matrix Power Series 矩阵

#include #include #include #include #include #include using namespace std; #define LL __int64 ...
• a601025382s
• 2013年08月22日 21:13
• 1222

## 构造矩阵解决问题 【nyoj299 Matrix Power Series】

• y990041769
• 2014年10月01日 10:37
• 1643

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

• AC_Gibson
• 2015年06月09日 16:10
• 465

## POJ 3233 - Matrix Power Series(等比矩阵求和)

• kalilili
• 2015年04月07日 22:28
• 1030

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

• rowanhaoa
• 2014年03月11日 16:48
• 1869

## Matrix Power Series（乘法矩阵）

Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + …...
• userluoxuan
• 2014年08月06日 19:37
• 513

## Matrix Power Series

Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 16...
• viphong
• 2015年04月11日 08:45
• 490

## Matrix Power Series（矩阵快速幂+求幂和）

Link：http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS...
• Enjoying_Science
• 2015年08月05日 16:32
• 416

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

• u013013910
• 2014年09月17日 17:06
• 1074

举报原因： 您举报文章：poj 3233 --- Matrix Power Series (二分,矩阵) 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)