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. 解决maven无法加载本地lib/下的jar包问题(程序包XXX不存在)

    这次一个项目用到maven编译,我在本地开发的时候jar包都是放在WEB-INF/lib目录下,通过 BuildPath将jar包导入,然后用MyEclipse中的:maven package命令打成 ...

  2. 定时任务-----Springboot中使用Scheduled做定时任务----http://www.cnblogs.com/lirenqing/p/6596557.html

    Springboot中使用Scheduled做定时任务---http://www.cnblogs.com/lirenqing/p/6596557.html 已经验证的方案: pom文件加入依赖 < ...

  3. node.js 利用流实现读写同步,边读边写

    //10个数 10个字节,每次读4b,写1b let fs=require("fs"); function pipe(source,target) { //先创建可读流,再创建可写 ...

  4. codevs2449 骑士精神

    题目描述 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标 ...

  5. B. Code For 1 分治

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  6. 29、Java并发性和多线程-非阻塞算法

    以下内容转自http://ifeve.com/non-blocking-algorithms/: 在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法.在绝大多数项目中,在 ...

  7. JAVA包装类的缓存范围

    JAVA包装类的缓存范围 前两天面试遇到两个关于JAVA源码的问题,记录下来提醒自己. 1.写出下面的输出结果 System.out.println(Integer.valueOf("100 ...

  8. 高效开发之SASS篇 灵异留白事件——图片下方无故留白 你会用::before、::after吗 link 与 @import之对比 学习前端前必知的——HTTP协议详解 深入了解——CSS3新增属性 菜鸟进阶——grunt $(#form :input)与$(#form input)的区别

    高效开发之SASS篇   作为通往前端大神之路的普通的一只学鸟,最近接触了一样稍微高逼格一点的神器,特与大家分享~ 他是谁? 作为前端开发人员,你肯定对css很熟悉,但是你知道css可以自定义吗?大家 ...

  9. cocos2d-x 多触点监听

    [cpp] view plaincopy //首先到cocos2d-x项目下的ios目录下.找到AppController.mm文件,在函数 didFinishLaunchingWithOptions ...

  10. URAL 1822. Hugo II&#39;s War 树的结构+二分

    1822. Hugo II's War Time limit: 0.5 second Memory limit: 64 MB The glorious King Hugo II has declare ...