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、jupyter-notebook 的金融领域用户交易行为分析

    说明:本文重在说明交易数据统计.分析方法,所有数据均为生成的数据 时间原因代码未定义成函数 统计指标:1.用户单日交易行为数据 2.按小时为计算单位,统计用户行为数据(旨在求得一天24小时中每个小时的 ...

  2. Python json & pickle & shelve模块

    json & pickle 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇 ...

  3. codechef 营养题 第一弹

    第一弾が始まる! 定期更新しない! 来源:http://wenku.baidu.com/link?url=XOJLwfgMsZp_9nhAK15591XFRgZl7f7_x7wtZ5_3T2peHh5 ...

  4. 威纶通 与 信捷XC\XD系列PLC 通讯

    第一次使用信捷XD系列PLC正式做个项目,用的触摸屏为威纶通的 MT6071iP (注意:下面内容同样适用于 信捷XC系列PLC ,除信捷XC与XD系列编程软件不一样,其余接线设置实测均一样 ) 目前 ...

  5. Leetcode 135.分糖果

    分发糖果 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果. 相邻的孩 ...

  6. 【BZOJ4514】数字配对(费用流)

    题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci× ...

  7. tyvj3737 逐个击破

    描述 三大战役的平津战场上,傅作义集团在以北平.天津为中心,东起唐山西至张家口的铁路线上摆起子一字长蛇阵,并企图在溃败时从海上南逃或向西逃窜.为了就地歼敌不让其逃走,mzd制定了先切断敌人东洒两头退路 ...

  8. A - 不容易系列之(3)―― LELE的RPG难题 简单递推

    人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即"可乐"),经过多方打探,某资深Cole终于知道了原因,原来,LELE最近研 ...

  9. SpringMvc切面校验JavaBean及基础类型

    先配置好aop需要的配置,文:https://www.cnblogs.com/jiangxishicheng/p/10896498.html 编写校验切面类: package com.aspect;/ ...

  10. ISATAP隧道方式接入IPv6和RRAS(Windows路由与远程访问)似乎是冲突的

    在启用了RRAS的NAT服务器上设置ISATAP隧道,虽然能正常获取IPv6地址,但是IPv6网络实际是不通的...