Matrix Power Series
Time Limit: 3000MS   Memory Limit: 131072K
Total Submissions: 11954   Accepted: 5105

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
 
 
题意:已知一个n*n的矩阵A,和一个正整数k,求S = A + A2 + A3 + … + Ak

 
思路:矩阵快速幂。首先我们知道 A^x 可以用矩阵快速幂求出来(具体可见poj 3070)。其次可以对k进行二分,每次将规模减半,分k为奇偶两种情况,如当k = 6和k = 7时有:
      k = 10 有: S(9) = ( A^1+A^2+A^3+A^4+ A^5 ) + A^5 * ( A^1+A^2+A^3+A^4+A^5 ) = S(5) + A^5 * S(5) 
      k = 5 有: S(5) = ( A^1+A^2 ) + A^3 + A^3 * ( A^1+A^2 ) = S(2) + A^3 + A^3 * S(2)
    k = 2 有 :  S(2) = A^1 + A^2 = S(1) + A^1 * S(1)
 从上面几个式子可以发现,当k为奇数或者偶数的区别,具体见代码中的solve函数。(solve函数的功能:递推到底层,也就是到 k = 1时回退,最后一步一步求出,弄懂递推的思想,这题也就明白了),当然定义成数组,然后再进行一些预处理,效率会更高些。
 
#include<iostream>
#include<cstdio>
#include<cstring> using namespace std; int n,k,mod; struct Matrix{
int arr[][];
}; Matrix unit,init; Matrix Mul(Matrix a,Matrix b){
Matrix c;
for(int i=;i<n;i++)
for(int j=;j<n;j++){
c.arr[i][j]=;
for(int k=;k<n;k++)
c.arr[i][j]=(c.arr[i][j]+a.arr[i][k]*b.arr[k][j]%mod)%mod;
c.arr[i][j]%=mod;
}
return c;
} Matrix Pow(Matrix a,Matrix b,int x){
while(x){
if(x&){
b=Mul(b,a);
}
x>>=;
a=Mul(a,a);
}
return b;
} Matrix Add(Matrix a,Matrix b){
Matrix c;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
c.arr[i][j]=(a.arr[i][j]+b.arr[i][j])%mod;
return c;
} Matrix solve(int x){
if(x==)
return init;
Matrix res=solve(x/),cur;
if(x&){
cur=Pow(init,unit,x/+);
res=Add(res,Mul(cur,res));
res=Add(res,cur);
}else{
cur=Pow(init,unit,x/);
res=Add(res,Mul(cur,res));
}
return res;
} int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d%d%d",&n,&k,&mod)){
for(int i=;i<n;i++)
for(int j=;j<n;j++){
scanf("%d",&init.arr[i][j]);
unit.arr[i][j]=(i==j?:);
}
Matrix res=solve(k);
for(int i=;i<n;i++){
for(int j=;j<n-;j++)
printf("%d ",res.arr[i][j]);
printf("%d\n",res.arr[i][n-]);
}
}
return ;
}

最新文章

  1. 八、RFCOMM
  2. nginx添加proxy_cache模块做缓存服务器
  3. python 集合、函数和文件操作
  4. js判断移动端是否安装某款app的多种方法
  5. PHP实现 bitmap 位图排序 求交集
  6. python 获取类的属性
  7. Win32 GDI 非矩形区域剪裁,双缓冲技术
  8. CSS 布局Float 【3】
  9. ZOJ 2562 More Divisors(高合成数)
  10. SQL拼接方法
  11. 第2章 rsync(二):inotify+rsync详细说明和sersync
  12. JMeter脚本录制
  13. Tomcat9使用免费的Https证书加密网站
  14. antd pro 分支
  15. sql parser
  16. Liunx/RHEL6.5 Oracle11 安装记录[缺少依赖包的解决方案]
  17. Python虚拟环境和包管理工具Pipenv的使用详解--看完这一篇就够了
  18. gflags命令行参数解析
  19. 几款主流 NoSql 数据库的对比(转)
  20. c# 单实例运行

热门文章

  1. [转]C++之运算符重载(1)
  2. poj 1469 COURSES 题解
  3. go语言之进阶篇值语义和引用语义
  4. Python爬虫——使用 lxml 解析器爬取汽车之家二手车信息
  5. [置顶] Spring中自定义属性编辑器
  6. Cognos开发自定义排序规则的报表和自定义排名报表
  7. uva 213 - Message Decoding (我认为我的方法要比书上少非常多代码,不保证好……)
  8. [Algorithm] Search for matching words
  9. 王立平-- android:layout_weight
  10. hadoop伪分布集群搭建