首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

poj3233 - Matrix Power Series

  • 24-03-05 07:00
  • 2819
  • 5769
blog.csdn.net

                                    想看更多的解题报告: http://iyenn.com/rec/1824570.html
                                     转载请注明出处:
http://blog.csdn.net/wangjian8006

题目大意:给你A矩阵,A矩阵是n*n的一个矩阵,现在要你求S = A + A^2 + A^3 + … + A^k.
那么s一定也是一个N*N的矩阵,最后要你输出s,并且s的每一个元素对m取余数

 

解题思路:因为S可以看成S=A(I+A(I+A(I+...A(I+A)))) (I是单位矩阵)

拿k=3举例S=A(I+A(I+A))

那么我们想,可不可以构造一个矩阵T使得T*T(因为是k次幂)这样乘下去每次可以得到A*(A+I)

那么肯定T有个两个元素就是A与I

那么假设:T={A  I }
                        I  I
那么T=T*T={A*A+I*I       A*I+I*I}
                      A*I+I*I           I*I+I*I
这样存在一个I*(A+I)的式子 ,当T再乘以T的时候会出现A(A+I)

这个时候我们可以简化将T={A  I}  

                                            0   I

这样可以简化很多计算T*T={A*A   A*I+I*I}
                                           0           I

那么容易得到T^(K+1)={A^(K+1)           I+A+A^2+A^3+...+A^K}
                                         0                                I

这样我们只需要算T的k+1次幂就可以了

 


而k如此庞大所以需要二分来对T求k+1次幂

对T求快速幂:
首先我们知道A^19=A^16*A^2*A^1,因为19=B(10011)


那么就这样,拿A总是去和本身去乘,那么就可以取到 A A^2 A^4 A^8 A^16...


然后问A A^2 A^4 A^8 A^16 ...这么多项取与不取的抉择
其实就是一个求二进制的这样一个过程
19%2=1 那么A取进来
19/2=9
9%2=1 那么A^2取进来
9/2=4
4%2=0 那么A^4不用取进来
4/2=2
2%2=0 那么A^8不用去进来
2/2=1
1%2=1 那么A^16取进来
1/2=0 计算完毕

  1. /*
  2. Memory 312K
  3. Time 313MS
  4. */
  5. #include
  6. #include
  7. using namespace std;
  8. #define MAXV 70
  9. typedef struct{
  10. int r,c; //c行r列
  11. int mat[MAXV][MAXV];
  12. }Matrix;
  13. Matrix ans,cnt;
  14. int n,k,m;
  15. void Input(){
  16. int i,j;
  17. /*构造B矩阵*/
  18. memset(cnt.mat,0,sizeof(cnt.mat));
  19. memset(ans.mat,0,sizeof(ans.mat));
  20. for(i=0;i
  21. for(j=0;j
  22. scanf("%d",&cnt.mat[i][j]);
  23. }
  24. for(i=0;i
  25. cnt.mat[i+n][i+n]=cnt.mat[i][i+n]=1;
  26. ans.mat[i][i]=ans.mat[i+n][i+n]=1;
  27. }
  28. /*对矩阵B和B^(k+1)初始化*/
  29. cnt.c=cnt.r=2*n;
  30. ans.c=ans.r=2*n;
  31. }
  32. Matrix MatrixMul(Matrix x,Matrix y){ //矩阵乘法
  33. Matrix t;
  34. int i,j,v;
  35. memset(t.mat,0,sizeof(t.mat));
  36. t.c=x.c;
  37. t.r=y.r;
  38. for(i=0;i
  39. for(j=0;j
  40. for(v=0;v
  41. t.mat[i][j]+=((x.mat[i][v]*y.mat[v][j])%m);
  42. t.mat[i][j]=t.mat[i][j]%m;
  43. }
  44. return t;
  45. }
  46. void Binary(){
  47. //二分快速幂
  48. k++;
  49. while(k){
  50. if(k & 1) ans=MatrixMul(ans,cnt);
  51. cnt=MatrixMul(cnt,cnt);
  52. k=k>>1;
  53. }
  54. }
  55. void Output(){
  56. /*输出的时候要减去一个单位矩阵*/
  57. int i,j;
  58. for(i=0;i
  59. for(j=0;j
  60. if(i!=j)
  61. printf("%d ",ans.mat[i][j+n]);
  62. else
  63. printf("%d ",ans.mat[i][j+n]-1);
  64. printf("\n");
  65. }
  66. }
  67. int main(){
  68. while(~scanf("%d%d%d",&n,&k,&m)){
  69. Input();
  70. Binary();
  71. Output();
  72. }
  73. return 0;
  74. }


 

 

 

注:本文转载自blog.csdn.net的wangjian8006的文章"http://blog.csdn.net/wangjian8006/article/details/7868864"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top