先从最基础的矩阵快速幂加速递推开始。

HDU 1005 Number Sequence

|f[n-2],f[n-1]|* |0 B| =|f[n-1], B*f[n-2]+A*f[n-1]|=|f[n-1],f[n]|

          |1 A|

建立矩阵如上然后利用快速幂求解即可。答案是mat[0][1]。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<map>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<cmath>
  11. #include<set>
  12. #include<string>
  13. #define INF 1000000005
  14. #define LL long long
  15. using namespace std;
  16. ;
  17. struct Matrix
  18. {
  19. int n,m;
  20. int a[MAXN][MAXN];
  21. ,)
  22. {
  23. n=x;
  24. m=y;
  25. memset(a,,sizeof(a));
  26. }
  27. Matrix operator * (const Matrix &b)const
  28. {
  29. Matrix tmp;
  30. tmp.clear(n,b.m);
  31. ; i<n; ++i)
  32. ; j<b.m; ++j)
  33. ; k<m; ++k)
  34. {
  35. tmp.a[i][j]+=a[i][k]*b.a[k][j];
  36. tmp.a[i][j]%=;
  37. }
  38. return tmp;
  39. }
  40. };
  41. Matrix quickPow(Matrix mat,int n)
  42. {
  43. Matrix res;
  44. res.clear(,);
  45. res.a[][]=res.a[][]=;
  46. while(n)
  47. {
  48. ) res=res*mat;
  49. mat=mat*mat;
  50. n=n>>;
  51. }
  52. return res;
  53. }
  54. int main()
  55. {
  56. int A,B,n;
  57. while(scanf("%d%d%d",&A,&B,&n)!=EOF)
  58. {
  59. if(!A&&!B&&!n) break;
  60. ||n==)
  61. {
  62. puts(");
  63. continue;
  64. }
  65. Matrix mat;
  66. mat.clear(,);
  67. mat.a[][]=;
  68. mat.a[][]=B;
  69. mat.a[][]=;
  70. mat.a[][]=A;
  71. Matrix f;
  72. f.clear(,);
  73. f.a[][]=;
  74. f.a[][]=;
  75. n-=;
  76. Matrix s=f*quickPow(mat,n);
  77. printf(][])%);
  78. }
  79. ;
  80. }

HDU 4920 Matrix multiplication

矩阵乘法,直接算会超时。由于是模3,所以0很多,也就是稀疏矩阵。可以优化。

参见下文:http://www.cnblogs.com/jackiesteed/articles/2021604.html

  1. #include<iostream>
  2. #include<vector>
  3. #include<map>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<string>
  10. #define LL long long
  11. using namespace std;
  12. ][],B[][];
  13. ][];
  14. int n;
  15. int main()
  16. {
  17. int n;
  18. while(scanf("%d",&n)!=EOF)
  19. {
  20. ; i<=n; ++i)
  21. ; j<=n; ++j)
  22. {
  23. scanf("%d",&A[i][j]);
  24. A[i][j]%=;
  25. }
  26. ; i<=n; ++i)
  27. ; j<=n; ++j)
  28. {
  29. scanf("%d",&B[i][j]);
  30. B[i][j]%=;
  31. }
  32. memset(C,,sizeof(C));
  33. ; i<=n; ++i)
  34. ; j<=n; ++j)
  35. {
  36. ) continue;
  37. ; k<=n; ++k)
  38. C[i][k]+=A[i][j]*B[j][k];
  39. }
  40. ; i<=n; ++i)
  41. {
  42. ; j<=n; ++j)
  43. ) printf();
  44. );
  45. printf("\n");
  46. }
  47. }
  48. ;
  49. }

HDU 1575 Tr A

求矩阵的迹。直接快速幂即可。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<map>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<cmath>
  11. #include<set>
  12. #include<string>
  13. #define INF 1000000005
  14. #define LL long long
  15. using namespace std;
  16. ;
  17. struct Matrix
  18. {
  19. int n,m;
  20. int a[MAXN][MAXN];
  21. ,)
  22. {
  23. n=x;
  24. m=y;
  25. memset(a,,sizeof(a));
  26. }
  27. Matrix operator * (const Matrix &b)const
  28. {
  29. Matrix tmp;
  30. tmp.clear(n,b.m);
  31. ; i<n; ++i)
  32. ; j<b.m; ++j)
  33. {
  34. ; k<b.m; ++k)
  35. {
  36. ==a[i][j]) continue;//优化!
  37. tmp.a[i][k]+=a[i][j]*b.a[j][k];
  38. tmp.a[i][k]%=;
  39. }
  40. }
  41. return tmp;
  42. }
  43. void setOne(int x)
  44. {
  45. clear(x,x);
  46. ; i<x; ++i)
  47. a[i][i]=;
  48. }
  49. };
  50. Matrix one;
  51. Matrix quickPow(Matrix mat,int n)
  52. {
  53. Matrix res=one;
  54. while(n)
  55. {
  56. ) res=res*mat;
  57. mat=mat*mat;
  58. n=n>>;
  59. }
  60. return res;
  61. }
  62. int main()
  63. {
  64. int T;
  65. scanf("%d",&T);
  66. while(T--){
  67. int n,k;
  68. scanf("%d%d",&n,&k);
  69. one.setOne(n);
  70. Matrix mat;
  71. mat.clear(n,n);
  72. ;i<n;++i)
  73. ;j<n;++j)
  74. scanf("%d",&mat.a[i][j]);
  75. mat=quickPow(mat,k);
  76. ;
  77. ;i<n;++i)
  78. {
  79. ans+=mat.a[i][i];
  80. ans%=;
  81. }
  82. printf("%d\n",ans);
  83. }
  84. ;
  85. }

HDU 1757 A Simple Math Problem

一个简单的递推,建立矩阵后,快速幂。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<map>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<cmath>
  11. #include<set>
  12. #include<string>
  13. #define INF 1000000005
  14. #define LL long long
  15. using namespace std;
  16. ;
  17. int M;
  18. struct Matrix
  19. {
  20. int n,m;
  21. int a[MAXN][MAXN];
  22. ,)
  23. {
  24. n=x;
  25. m=y;
  26. memset(a,,sizeof(a));
  27. }
  28. Matrix operator * (const Matrix &b)const
  29. {
  30. Matrix tmp;
  31. tmp.clear(n,b.m);
  32. ; i<n; ++i)
  33. ; j<b.m; ++j)
  34. {
  35. ; k<b.m; ++k)
  36. {
  37. ==a[i][j]) continue;//优化!
  38. tmp.a[i][k]+=a[i][j]*b.a[j][k];
  39. tmp.a[i][k]%=M;
  40. }
  41. }
  42. return tmp;
  43. }
  44. void setOne(int x)
  45. {
  46. clear(x,x);
  47. ; i<x; ++i)
  48. a[i][i]=;
  49. }
  50. };
  51. Matrix one;
  52. Matrix quickPow(Matrix mat,int n)
  53. {
  54. Matrix res=one;
  55. while(n)
  56. {
  57. ) res=res*mat;
  58. mat=mat*mat;
  59. n=n>>;
  60. }
  61. return res;
  62. }
  63. int main()
  64. {
  65. int k;
  66. one.setOne();
  67. while(scanf("%d%d",&k,&M)!=EOF)
  68. {
  69. Matrix mat;
  70. mat.clear(,);
  71. ; i<; ++i)
  72. mat.a[i+][i]=;
  73. ; i<; ++i)
  74. scanf(-i][]);
  75. ) printf("%d\n",k%M);
  76. else
  77. {
  78. Matrix f;
  79. f.clear(,);
  80. ; i<; ++i)
  81. f.a[][i]=i;
  82. k-=;
  83. f=f*quickPow(mat,k);
  84. printf(][]);
  85. }
  86. }
  87. ;
  88. }

UVa 10870  Recurrences

与上面类型相似的题,建立矩阵,再快速幂加速。注意会超int。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<map>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<cmath>
  11. #include<set>
  12. #include<string>
  13. #define INF 1000000005
  14. #define LL long long
  15. using namespace std;
  16. ;
  17. int M;
  18. struct Matrix
  19. {
  20. int n,m;
  21. LL a[MAXN][MAXN];
  22. ,)
  23. {
  24. n=x;
  25. m=y;
  26. memset(a,,sizeof(a));
  27. }
  28. Matrix operator * (const Matrix &b)const
  29. {
  30. Matrix tmp;
  31. tmp.clear(n,b.m);
  32. ; i<n; ++i)
  33. ; j<b.m; ++j)
  34. {
  35. ; k<b.m; ++k)
  36. {
  37. ==a[i][j]) continue;//优化!
  38. tmp.a[i][k]+=a[i][j]*b.a[j][k];
  39. tmp.a[i][k]%=M;
  40. }
  41. }
  42. return tmp;
  43. }
  44. void setOne(int x)
  45. {
  46. clear(x,x);
  47. ; i<x; ++i)
  48. a[i][i]=;
  49. }
  50. };
  51. Matrix one;
  52. Matrix quickPow(Matrix mat,LL n)
  53. {
  54. Matrix res=one;
  55. while(n)
  56. {
  57. ) res=res*mat;
  58. mat=mat*mat;
  59. n=n>>;
  60. }
  61. return res;
  62. }
  63. int main()
  64. {
  65. int d,n;
  66. while(scanf("%d%d%d",&d,&n,&M)!=EOF)
  67. {
  68. if(!d&&!n&&!M) break;
  69. one.setOne(d);
  70. Matrix mat;
  71. mat.clear(d,d);
  72. ; i<d; ++i)
  73. mat.a[i+][i]=;
  74. ; i<d; ++i)
  75. scanf(-i][d-]);
  76. Matrix f;
  77. f.clear(,d);
  78. ; i<d; ++i)
  79. scanf(][i]);
  80. if(n<=d)
  81. printf(][n-]%M);
  82. else
  83. {
  84. n-=d;
  85. f=f*quickPow(mat,n);
  86. printf(][d-]%M);
  87. }
  88. }
  89. ;
  90. }

POJ 3734 Blocks

递推+矩阵快速幂。

设计状态的时候要考虑所有可能的情况,保证无重复无遗漏,再考虑转移。最后用矩阵加速。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<map>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<cmath>
  11. #include<set>
  12. #include<string>
  13. #define INF 1000000005
  14. #define LL long long
  15. using namespace std;
  16. ;
  17. ;
  18. struct Matrix
  19. {
  20. int n,m;
  21. int a[MAXN][MAXN];
  22. Matrix(,):n(x),m(y)
  23. {
  24. memset(a,,sizeof(a));
  25. }
  26. ,)
  27. {
  28. n=x;
  29. m=y;
  30. memset(a,,sizeof(a));
  31. }
  32. Matrix operator * (const Matrix &b)const
  33. {
  34. Matrix tmp;
  35. tmp.clear(n,b.m);
  36. ; i<n; ++i)
  37. ; j<b.m; ++j)
  38. {
  39. ; k<b.m; ++k)
  40. {
  41. ==a[i][j]) continue;//ÓÅ»¯£¡
  42. tmp.a[i][k]+=a[i][j]*b.a[j][k];
  43. tmp.a[i][k]%=M;
  44. }
  45. }
  46. return tmp;
  47. }
  48. void setOne(int x)
  49. {
  50. clear(x,x);
  51. ; i<x; ++i)
  52. a[i][i]=;
  53. }
  54. };
  55. Matrix one;
  56. Matrix quickPow(Matrix mat,int n)
  57. {
  58. Matrix res=one;
  59. while(n)
  60. {
  61. ) res=res*mat;
  62. mat=mat*mat;
  63. n=n>>;
  64. }
  65. return res;
  66. }
  67. int main()
  68. {
  69. one.setOne();
  70. int T;
  71. scanf("%d",&T);
  72. while(T--)
  73. {
  74. int n;
  75. scanf("%d",&n);
  76. Matrix mat(,);
  77. mat.a[][]=,mat.a[][]=,mat.a[][]=;
  78. mat.a[][]=,mat.a[][]=,mat.a[][]=;
  79. mat.a[][]=,mat.a[][]=,mat.a[][]=;
  80. Matrix f(,);
  81. f.a[][]=;
  82. Matrix ans=f*quickPow(mat,n);
  83. printf(][]);
  84. }
  85. ;
  86. }

POJ 3420 Quad Tiling

这个题的关键是在求递推式。

设dp[i]表示填满前i个方块的种数。那么从dp[i-1]转移有1种情况,从dp[i-2]转移有4种情况,在之后从dp[i-a],如果a是奇数有2种情况,a是偶数有3种情况。

这样最终化简得dp[i]=dp[i-1]+5dp[i-2]+dp[i-3]-dp[i-4]

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<map>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<cmath>
  11. #include<set>
  12. #include<string>
  13. #define INF 1000000005
  14. #define LL long long
  15. using namespace std;
  16. ;
  17. int M;
  18. struct Matrix
  19. {
  20. int n,m;
  21. int a[MAXN][MAXN];
  22. Matrix(,):n(x),m(y)
  23. {
  24. memset(a,,sizeof(a));
  25. }
  26. ,)
  27. {
  28. n=x;
  29. m=y;
  30. memset(a,,sizeof(a));
  31. }
  32. Matrix operator * (const Matrix &b)const
  33. {
  34. Matrix tmp;
  35. tmp.clear(n,b.m);
  36. ; i<n; ++i)
  37. ; j<b.m; ++j)
  38. {
  39. ; k<b.m; ++k)
  40. {
  41. ==a[i][j]) continue;//优化
  42. tmp.a[i][k]+=a[i][j]*b.a[j][k];
  43. tmp.a[i][k]%=M;
  44. }
  45. }
  46. return tmp;
  47. }
  48. void setOne(int x)
  49. {
  50. clear(x,x);
  51. ; i<x; ++i)
  52. a[i][i]=;
  53. }
  54. };
  55. Matrix one;
  56. Matrix quickPow(Matrix mat,int n)
  57. {
  58. Matrix res=one;
  59. )
  60. {
  61. ) res=res*mat;
  62. mat=mat*mat;
  63. n=n>>;
  64. }
  65. return res;
  66. }
  67. int main()
  68. {
  69. int n;
  70. one.setOne();
  71. while(scanf("%d%d",&n,&M)!=EOF)
  72. {
  73. if(!n&&!M) break;
  74. Matrix mat(,);
  75. ; i<; ++i)
  76. mat.a[i+][i]=;
  77. mat.a[][]=-,mat.a[][]=,mat.a[][]=,mat.a[][]=;
  78. Matrix f(,);
  79. f.a[][]=,f.a[][]=,f.a[][]=,f.a[][]=;
  80. ) printf(][n]%M);
  81. else
  82. {
  83. n-=;
  84. Matrix s=f*quickPow(mat,n);
  85. printf(][]);
  86. }
  87. }
  88. ;
  89. }

ZOJ 3690 Choosing number

a[i]表示第i个人选小于等于k的数字的合法种数,a[i]=(k-1)*a[i]+k*b[i]

b[i]表示第i个人选大于等于k的数字的合法种数,b[i]=(m-k)*a[i]+(m-k)*b[i]

a[0]=0,b[0]=1,答案是a[n]+b[n]

建立矩阵快速幂计算即可。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cmath>
  4. #include<map>
  5. #include<algorithm>
  6. #include<cstring>
  7. #include<cstdio>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<cmath>
  11. #include<set>
  12. #include<string>
  13. #define INF 1000000005
  14. #define LL long long
  15. using namespace std;
  16. ;
  17. ;
  18. struct Matrix
  19. {
  20. int n,m;
  21. LL a[MAXN][MAXN];
  22. Matrix(,):n(x),m(y)
  23. {
  24. memset(a,,sizeof(a));
  25. }
  26. ,)
  27. {
  28. n=x;
  29. m=y;
  30. memset(a,,sizeof(a));
  31. }
  32. Matrix operator * (const Matrix &b)const
  33. {
  34. Matrix tmp;
  35. tmp.clear(n,b.m);
  36. ; i<n; ++i)
  37. ; j<m; ++j)
  38. {
  39. ; k<b.m; ++k)
  40. {
  41. ==a[i][j]) continue;//优化!
  42. tmp.a[i][k]+=a[i][j]*b.a[j][k];
  43. tmp.a[i][k]%=M;
  44. }
  45. }
  46. return tmp;
  47. }
  48. void setOne(int x)
  49. {
  50. clear(x,x);
  51. ; i<x; ++i)
  52. a[i][i]=;
  53. }
  54. };
  55. Matrix one;
  56. Matrix quickPow(Matrix mat,int n)
  57. {
  58. Matrix res=one;
  59. while(n)
  60. {
  61. ) res=res*mat;
  62. mat=mat*mat;
  63. n=n>>;
  64. }
  65. return res;
  66. }
  67. int main()
  68. {
  69. int n,m,k;
  70. one.setOne();
  71. while(scanf("%d%d%d",&n,&m,&k)!=EOF)
  72. {
  73. Matrix mat(,);
  74. mat.a[][]=k-,mat.a[][]=k;
  75. mat.a[][]=m-k,mat.a[][]=m-k;
  76. Matrix f(,);
  77. f.a[][]=,f.a[][]=;
  78. Matrix s=quickPow(mat,n)*f;
  79. printf(][]+s.a[][])%M);
  80. }
  81. ;
  82. }

ACM 矩阵题目整理的更多相关文章

  1. ACM 字符串 题目整理

    AC自动机 UVa 11468  Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...

  2. Noip往年题目整理

    Noip往年题目整理 张炳琪 一.历年题目 按时间倒序排序 年份 T1知识点 T2知识点 T3知识点 得分 总体 2016day1 模拟 Lca,树上差分 期望dp 144 挺难的一套题目,偏思维难度 ...

  3. NOIp初赛题目整理

    NOIp初赛题目整理 这个 blog 用来整理扶苏准备第一轮 csp 时所做的与 csp 没 有 关 系 的历年 noip-J/S 初赛题目,记录了一些我从不知道的细碎知识点,还有一些憨憨题目,不定期 ...

  4. ACM 暴力搜索题 题目整理

    UVa 129 Krypton Factor 注意输出格式,比较坑爹. 每次要进行处理去掉容易的串,统计困难串的个数. #include<iostream> #include<vec ...

  5. ACM - 动态规划专题 题目整理

    CodeForces 429B  Working out 预处理出从四个顶点到某个位置的最大权值,再枚举相遇点,相遇的时候只有两种情况,取最优解即可. #include<iostream> ...

  6. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  7. 第八届蓝桥杯c/c++省赛题目整理

    第一题 标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都 ...

  8. ACM金牌选手整理的【LeetCode刷题顺序】

    算法和数据结构知识点图 首先,了解算法和数据结构有哪些知识点,在后面的学习中有 大局观,对学习和刷题十分有帮助. 下面是我花了一天时间花的算法和数据结构的知识结构,大家可以看看. 后面是为大家 精心挑 ...

  9. 内工大acm校赛--整理代码

    题目:小明搜到一行无缩进无换行代码,请帮小明整理代码.无for语句和case语句,而且只有一个主函数.你只要控制注意“:”“{”“}”这三个符号带来的缩进和换行效果就行. Input: 输入只有一行, ...

随机推荐

  1. android界面横屏和竖屏的切换

    关于android横屏和竖屏的切换网上给了很多种.但是有些介绍的方法都是在android旧版本上. 我现在把握用到的情况写下来用于备忘: android 版本:4.0 - 4.4 要求:android ...

  2. VS2012下基本类型大小

  3. hadoop运维经验

    0.优化:http://dongxicheng.org/mapreduce/hadoop-optimization-0/ http://dongxicheng.org/mapreduce/hadoop ...

  4. minicom 使用教程

    因为现在电脑基本不配备串行接口,所以,usb转串口成为硬件调试时的必然选择.目前知道的,PL2303的驱动是有的,在dev下的名称是ttyUSB#. minicom,tkterm都是linux下应用比 ...

  5. c++ 指针常量,常量指针

    当const遇到指针 一般来说,const修饰指针可以分为下面的集中情况. 描述 例子 含义 备注 const在*的左边 const int *b=&a; int const *b=& ...

  6. Sprint(第一天11.14)

    Sprint1第一阶段 1.类名:软件工程-第一阶段 2.时间:11.14-11.23 3.选题内容:点餐系统 4.团队博客地址:http://www.cnblogs.com/iamCarson/ 团 ...

  7. 开源.NET FTP组件edtFTPnet 用法

    edtFTPnet官方网站:http://www.enterprisedt.com/products/edtftpnet/ 目前最新版本为2.2.3,下载后在bin目录中找到edtFTPnet.dll ...

  8. ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)

    最近在做一个电商项目,其中商品搜索中出现一个奇怪的现象,根据某个字段排序的时候会出现商品数量减少的情况.按照一般路要么查不出来,要么正常显示,为什么增加了按照销量排序就会出现查询结果减少的情况. 查了 ...

  9. Windows里面的hosts文件

    一.什么是Hosts文件? hosts文件是一个用于储存计算机网络中各节点信息的计算机文件.这个文件负责将主机名映射到相应的IP地址.hosts文件通常用于补充或取代网络中DNS的功能.和DNS不同的 ...

  10. 【转载】CSS 伪类-:before和:after

    :before和:after的作用就是在指定的元素内容(而不是元素本身)之前或者之后插入一个包含content属性指定内容的行内元素,最基本的用法如下: #example:before { conte ...