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
解题思路:等比矩阵求和,采用递归二分的方法。

上图就给出了求前k项等比矩阵的和的递推式,解法采用递归来求和比较直观,也很好理解。
AC代码(1704ms):
 #include<iostream>
#include<cstring>
using namespace std;
const int maxn=;
int n,k,mod;
struct Matrix{int m[maxn][maxn];}init;
Matrix add(Matrix a,Matrix b){//矩阵加法
Matrix c;
for(int i=;i<n;++i)
for(int j=;j<n;++j)
c.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
return c;
}
Matrix mul(Matrix a,Matrix b){//矩阵乘法
Matrix c;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
c.m[i][j]=;
for(int k=;k<n;k++)
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
}
}
return c;
}
Matrix quick_power(Matrix a,int x){//矩阵快速幂
Matrix b;memset(b.m,,sizeof(b.m));
for(int i=;i<n;++i)b.m[i][i]=;//单位矩阵
while(x){
if(x&)b=mul(b,a);
a=mul(a,a);x>>=;
}
return b;
}
Matrix sum(Matrix s,int k){//求前k项和
if(k==)return s;//递归出口:当幂指数为1时,返回当前的矩阵
Matrix tmp;memset(tmp.m,,sizeof(tmp.m));//暂存保存中间的矩阵
for(int i=;i<n;++i)tmp.m[i][i]=;//单位矩阵
tmp=add(tmp,quick_power(s,k>>));//计算1+A^{k/2}
tmp=mul(tmp,sum(s,k>>));//计算(1+A^{k/2})*(A + A^2 + A^3 + … + A^{k/2})=(1+A^{k/2})*(S_{k/2})
if(k&)tmp=add(tmp,quick_power(s,k));//若k是奇数,则加上A^k
return tmp;//返回前k项的值
}
void print_rectangle(Matrix r){
for(int i=;i<n;++i)
for(int j=;j<n;++j)
cout<<r.m[i][j]<<((j==n-)?"\n":" ");
}
int main(){
while(cin>>n>>k>>mod){
for(int i=;i<n;++i)
for(int j=;j<n;++j)
cin>>init.m[i][j];
init=sum(init,k);
print_rectangle(init);
}
return ;
}

采用分块矩阵求解可以减少很多时间,具体推导可以结合下图:

矩阵中套矩阵,效率上比上一种方法更快,实际上是2n×2n的矩阵快速幂。就样例展开等式左边的矩阵:

那么最终的答案就是等式右边矩阵中左下角的子矩阵减去单位矩阵,注意某个元素值减-1之后可能为-1,那么此时只需再加上mod即可。

AC代码(610ms):

 #include<iostream>
#include<cstring>
using namespace std;
const int maxn=;
struct Matrix{int m[maxn][maxn];}init;
int n,k,mod;
Matrix mul(Matrix a,Matrix b){//矩阵乘法
Matrix c;
for(int i=;i<*n;i++){//矩阵大小扩大两倍,枚举第一个矩阵的行
for(int j=;j<*n;j++){//枚举第二个矩阵的列
c.m[i][j]=;
for(int k=;k<*n;k++)//枚举第一个矩阵的列
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
}
}
return c;
}
Matrix POW(Matrix a,int x){//矩阵快速幂
Matrix b;memset(b.m,,sizeof(b.m));
for(int i=;i<*n;++i)b.m[i][i]=;//构造单位矩阵
while(x){
if(x&)b=mul(b,a);
a=mul(a,a);x>>=;
}
return b;
}
void print_rectangle(Matrix r){
for(int i=;i<n;++i){
for(int j=;j<n;++j){
if(i==j)r.m[n+i][j]-=;
if(r.m[n+i][j]<)r.m[n+i][j]+=mod;//左下角子矩阵减去单位矩阵,减完可能小于0,因此需要加上mod再取余mod
cout<<r.m[n+i][j]<<((j==n-)?'\n':' ');
}
}
}
int main(){
while(cin>>n>>k>>mod){
memset(init.m,,sizeof(init.m));//全部初始化为0
for(int i=;i<n;++i){//首先初始化矩阵
for(int j=;j<n;++j)
cin>>init.m[i][j];
init.m[n+i][i]=init.m[n+i][n+i]=;//其余是单位矩阵
}
init=POW(init,k+);//求其前k+1项和(左下角包含单位矩阵,最后输出要减去单位矩阵)
print_rectangle(init);//打印等比矩阵A前k项和
}
return ;
}

题解报告:poj 3233 Matrix Power Series(矩阵快速幂)的更多相关文章

  1. POJ 3233 Matrix Power Series 矩阵快速幂

    设S[k] = A + A^2 +````+A^k. 设矩阵T = A[1] 0 E E 这里的E为n*n单位方阵,0为n*n方阵 令A[k] = A ^ k 矩阵B[k] = A[k+1] S[k] ...

  2. POJ 3233 Matrix Power Series 矩阵快速幂+二分求和

    矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html 直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是 sum=A+A2+...+ ...

  3. Poj 3233 Matrix Power Series(矩阵乘法)

    Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Description Given a n × n matrix A and ...

  4. poj 3233 Matrix Power Series 矩阵求和

    http://poj.org/problem?id=3233 题解 矩阵快速幂+二分等比数列求和 AC代码 #include <stdio.h> #include <math.h&g ...

  5. poj 3233 Matrix Power Series(矩阵二分,高速幂)

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 15739   Accepted:  ...

  6. POJ 3233:Matrix Power Series 矩阵快速幂 乘积

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 18450   Accepted:  ...

  7. POJ3233 Matrix Power Series 矩阵快速幂 矩阵中的矩阵

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 27277   Accepted:  ...

  8. POJ3233:Matrix Power Series(矩阵快速幂+二分)

    http://poj.org/problem?id=3233 题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加).输出的数据mod m.k ...

  9. POJ 3233 Matrix Power Series(矩阵高速功率+二分法)

    职务地址:POJ 3233 题目大意:给定矩阵A,求A + A^2 + A^3 + - + A^k的结果(两个矩阵相加就是相应位置分别相加).输出的数据mod m. k<=10^9.     这 ...

  10. POJ 3233 Matrix Power Series(矩阵等比求和)

    题目链接 模板题. #include <cstdio> #include <cstring> #include <iostream> #include <ma ...

随机推荐

  1. Python学习:ModuleNotFoundError: No module named 'pygal.i18n' 的解决方法

    最近在学<Python编程:从入门到实践>,16.2小结中 from pygal.i18n import COUNTRIES 获取两个字母的国别码,我用的pygal的版本是2.4.0(终端 ...

  2. STM32 配置PC13~PC15

    在STM32的数据手册的管脚分配图中可以看到:PC14与OSC32_IN公用一个引脚,PC15与OSC32_OUT公用一个引脚,它们的使用方法如下: 当LSE(低速外部时钟信号)开启时,这两个公用管脚 ...

  3. layui laypage 当前页刷新问题

    困扰了好几天的问题,终于找到答案了 在执行完代码后添加下面的代码实现当前页的刷新 $(".layui-laypage-btn").click(); 在解决问题的过程中,其实已经注意 ...

  4. 【codeforces 709C】Letters Cyclic Shift

    [题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...

  5. nyoj 63 小猴子下落

    小猴子下落 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 有一颗二叉树,最大深度为D,且所有叶子的深度都相同.所有结点从左到右从上到下的编号为1,2,3,····· ...

  6. HDU 1249 三角形的分割

    可以将三角形的三条边一条一条加进图形中观察 假设添加第n个三角形 前n-1个三角形将区域划分为sum[n-1] 第n个三角形每条边最多能经过前n-1个三角形每条三角形的两条边 , 一条边切完增加了 2 ...

  7. 回文质数 USACO

    时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 15 ...

  8. 最小生成树 D - Constructing Roads

    There are N villages, which are numbered from 1 to N, and you should build some roads such that ever ...

  9. Ubuntu 16.04安装uGet替代迅雷,并在Chrome中设置为默认下载器

    uGet是采用aria2作为下载后端,所以两个软件都必须同时安装. 1.安装uGet sudo add-apt-repository ppa:plushuang-tw/uget-stable sudo ...

  10. Spring/Maven/MyBatis配置文件结合properties文件使用

    使用properties文件也叫注入,比如把一些常用的配置项写入到这个文件,然后在Spring的XML配置文件中使用EL表达式去获取. 这种方式不只Spring可以使用,同样MyBatis也可以使用, ...