http://poj.org/problem?id=3233

题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加)。输出的数据mod m。k<=10^9。
这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。比如,当k=6时,有:
A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3)应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

代码如下:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <math.h>
  6. #include <queue>
  7. using namespace std;
  8.  
  9. struct matrix
  10. {
  11. int a[][];
  12. } init,res;
  13. int n,k,mod;
  14. matrix Mult(matrix x,matrix y)
  15. {
  16. matrix tmp;
  17. for(int i=; i<n; i++)
  18. {
  19. for(int j=; j<n; j++)
  20. {
  21. tmp.a[i][j]=;
  22. for(int k=; k<n; k++)
  23. tmp.a[i][j]=(tmp.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
  24. }
  25. }
  26. return tmp;
  27. }
  28. matrix Pow(matrix x,int k)
  29. {
  30. matrix tmp;
  31. for(int i=; i<n; i++)
  32. {
  33. for(int j=; j<n; j++)
  34. tmp.a[i][j]=(i==j);
  35. }
  36. while(k)
  37. {
  38. if(k&)
  39. tmp=Mult(tmp,x);
  40. k>>=;
  41. x=Mult(x,x);
  42. }
  43. return tmp;
  44. }
  45. matrix Add(matrix x,matrix y)
  46. {
  47. matrix tmp;
  48. for(int i=; i<n; i++)
  49. {
  50. for(int j=; j<n; j++)
  51. {
  52. tmp.a[i][j]=(x.a[i][j]+y.a[i][j])%mod;
  53. }
  54. }
  55. return tmp;
  56. }
  57. matrix Sum(matrix x,int k)
  58. {
  59. if(k==)
  60. return x;
  61. matrix tmp=Sum(x,k/),y;
  62. if(k&)
  63. {
  64. y=Pow(x,k/+);
  65. tmp=Add(Mult(y,tmp),tmp);
  66. return Add(tmp,y);
  67. }
  68. else
  69. {
  70. y=Pow(x,k/);
  71. return Add(Mult(y,tmp),tmp);
  72. }
  73. }
  74. int main()
  75. {
  76. while(scanf("%d%d%d",&n,&k,&mod)!=EOF)
  77. {
  78. for(int i=; i<n; i++)
  79. {
  80. for(int j=; j<n; j++)
  81. {
  82. scanf("%d",&init.a[i][j]);
  83. init.a[i][j]%=mod;
  84. }
  85. }
  86. res=Sum(init,k);
  87. for(int i=; i<n; i++)
  88. {
  89. for(int j=; j<n; j++)
  90. {
  91. if(j==) printf("%d",res.a[i][j]);
  92. else printf(" %d",res.a[i][j]);
  93. }
  94. printf("\n");
  95. }
  96. }
  97. return ;
  98. }

其他大神的想法:

题目分析:矩阵快速幂。首先我们知道 A^x 可以用矩阵快速幂求出来。其次可以对k进行二分,每次将规模减半,分k为奇偶两种情况,如当k = 6和k = 7时有:

      k = 6 有: S(6) = (1 + A^3) * (A + A^2 + A^3) = (1 + A^3) * S(3)。
      k = 7 有: S(7) = A + (A + A^4) * (A + A^2 + A^3) = A + (A + A^4) * S(3)。
 
ps:对矩阵定义成结构体Matrix,求S时用递归,程序会比较直观,好写一点。当然定义成数组,然后再进行一些预处理,效率会更高些。
 

POJ3233:Matrix Power Series(矩阵快速幂+二分)的更多相关文章

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

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

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

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

  3. POJ3233:Matrix Power Series(矩阵快速幂+递推式)

    传送门 题意 给出n,m,k,求 \[\sum_{i=1}^kA^i\] A是矩阵 分析 我们首先会想到等比公式,然后得到这样一个式子: \[\frac{A^{k+1}-E}{A-E}\] 发现要用矩 ...

  4. POJ3233 Matrix Power Series(矩阵快速幂+分治)

    Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak. ...

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

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

  6. 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] ...

  7. POJ3233 Matrix Power Series(快速幂求等比矩阵和)

    题面 \(solution:\) 首先,如果题目只要我们求\(A^K\) 那这一题我们可以直接模版矩乘快速幂来做,但是它现在让我们求$\sum_{i=1}^{k}{(A^i)} $ 所以我们思考一下这 ...

  8. POJ-3233 Matrix Power Series 矩阵A^1+A^2+A^3...求和转化

    S(k)=A^1+A^2...+A^k. 保利求解就超时了,我们考虑一下当k为偶数的情况,A^1+A^2+A^3+A^4...+A^k,取其中前一半A^1+A^2...A^k/2,后一半提取公共矩阵A ...

  9. POJ3233Matrix Power Series(矩阵快速幂)

    题意 题目链接 给出$n \times n$的矩阵$A$,求$\sum_{i = 1}^k A^i $,每个元素对$m$取模 Sol 考虑直接分治 当$k$为奇数时 $\sum_{i = 1}^k A ...

随机推荐

  1. WAMP设置默认访问目录

    打开httpd.conf 1.修改:DocumentRoot "F:/Project/Php" 2.修改 <Directory "F:/Project/Php&qu ...

  2. linux,shell中if else if的写法,if elif

    需求描述: 在写shell脚本的过程中,用到了if else的写法,突然有多个参数需要判断 那么就想到了if else if的用法,于是进行如下的测试. 测试过程: 1.写如下的测试脚本,进行多个值的 ...

  3. leetCode 33.Search in Rotated Sorted Array(排序旋转数组的查找) 解题思路和方法

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  4. iOS根据文字字数动态确定Label宽高

    我们有时候在写项目的时候,会碰到,意见反馈,还有其他地方,讲座活动细则等需要大篇展示的文本, 因为每次服务器返回的内容大小不一,所以需要动态的调整label的宽高: 在ios 6 的时候可以: -(v ...

  5. 查看网卡流量:nload

    nload命令用于查看网卡流量,用法如下: [root@localhost ~]$ yum install -y epel-release [root@localhost ~]$ yum instal ...

  6. Python 列表表达式与生成器表达式

    列表表达式: (1) 语法1:[表达式 for 变量 in 列表],表示把得到的每一个变量值都放到 for 前面的表达式中计算 ,然后生成一个列表(2) 语法2:[表达式 for 变量 in 列表 i ...

  7. 编译OSG的FreeType插件时注意的问题

    使用自己编译的freetype.lib,在编译osgdb_freetype插件项目时,报错LINK错误,找不到png的一堆函数 最简单的方式是不要使用PNG编译freetype.记住不要犯贱.

  8. STM32学习之路之入门篇

    2006年ARM公司推出了基于ARMV7架构的cortex系列的标准体系结构,以满足各种技术得不同性能要求,包含了A,R,M三个分工明确的系列 其中A系列面向复杂的尖端应用程序,用于运行开放式的复杂操 ...

  9. PHP webservice 接口实例

    原文地址,就不摘抄了 http://www.sky00.com/archives/91.html

  10. linux下jdk,tomcat的安装

    一.安装jdk 1.jdk下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.ht ...