题意:给一个递推式S(n) = a1*S(n-1)+...+aR*S(n-R),要求S(k)+S(2k)+...+S(nk)的值。

分析:看到n的大小和递推式,容易想到矩阵快速幂。但是如何转化呢?

首先看到

我们用A表示上面的递推式中的R*R的那个矩阵,那么对于前面那个向量,每次乘上A^k之后都会变成(S(n + k)...)
那么对于初始的向量( S(R) S(R - 1) ... S(1) ) 如果这个向量当中包括 S(k) 我们可以直接对于每次要算的 S( i * k) 求和
也就是说这个向量乘上( I + A^k + (A^k)^2 + (A^k)^3 + ... + (A^k)^(N - 1))之后对应的 S(k) 所在的那个位置就变成了要求的和
而对于那个矩阵型的等比数列求和可以直接用二分求和(常用的技巧),这样就可以在限制的时间内完成计算了  (Gatevin)

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #define Mod 1000000007
  7. #define ll long long
  8. using namespace std;
  9. #define N 100007
  10.  
  11. ll s[],a[];
  12. ll n;
  13. int r;
  14.  
  15. struct Matrix
  16. {
  17. ll m[][];
  18. Matrix()
  19. {
  20. memset(m,,sizeof(m));
  21. for(int i=;i<=;i++)
  22. m[i][i] = ;
  23. }
  24. };
  25.  
  26. Matrix Mul(Matrix a,Matrix b)
  27. {
  28. Matrix res;
  29. int i,j,k;
  30. for(i=;i<=r;i++)
  31. {
  32. for(j=;j<=r;j++)
  33. {
  34. res.m[i][j] = ;
  35. for(k=;k<=r;k++)
  36. res.m[i][j] = (res.m[i][j]+(a.m[i][k]*b.m[k][j]%Mod))%Mod;
  37. }
  38. }
  39. return res;
  40. }
  41.  
  42. Matrix add(Matrix a,Matrix b)
  43. {
  44. Matrix res;
  45. memset(res.m,,sizeof(res.m));
  46. int i,j;
  47. for(i=;i<=r;i++)
  48. for(j=;j<=r;j++)
  49. res.m[i][j] = (a.m[i][j]+b.m[i][j])%Mod;
  50. return res;
  51. }
  52.  
  53. Matrix fastm(Matrix a,ll b)
  54. {
  55. Matrix res;
  56. while(b)
  57. {
  58. if(b&1LL)
  59. res = Mul(res,a);
  60. a = Mul(a,a);
  61. b >>= ;
  62. }
  63. return res;
  64. }
  65.  
  66. Matrix getsum(Matrix a,ll b) //二分求矩阵等比数列和
  67. {
  68. Matrix I; //单位阵
  69. if(b == 1LL)
  70. return I;
  71. if(b&1LL)
  72. return add(getsum(a,b-1LL),fastm(a,b-1LL));
  73. else
  74. return Mul(getsum(a,b/2LL),add(I,fastm(a,b/2LL))); // (I+A^k+...+A^(n/2)k)*(I+A^(n/2)k)
  75. }
  76.  
  77. int main()
  78. {
  79. int t,i,j,k;
  80. scanf("%d",&t);
  81. while(t--)
  82. {
  83. scanf("%lld%d%d",&n,&r,&k);
  84. for(i=;i<=r;i++)
  85. scanf("%lld",&s[i]);
  86. for(i=;i<=r;i++)
  87. scanf("%lld",&a[i]);
  88. Matrix A;
  89. memset(A.m,,sizeof(A.m));
  90. for(i=;i<=r;i++) //构造矩阵
  91. {
  92. A.m[][i] = a[i];
  93. if(i < r)
  94. A.m[i+][i] = ;
  95. }
  96. //求 I+A^k+A^(2k)+...+A^(n-1)k
  97. Matrix base = fastm(A,k);
  98. Matrix ans = getsum(base,n);
  99. ll res = ;
  100. if(k <= r) //第k项在给出的数内
  101. {
  102. for(i=;i<=r;i++)
  103. res = (res + (s[i]*ans.m[r-k+][r-i+]%Mod))%Mod;
  104. printf("%lld\n",res%Mod);
  105. }
  106. else //否则先算出s[r+1]...s[k]
  107. {
  108. for(i=r+;i<=k;i++)
  109. {
  110. s[i] = ;
  111. for(j=;j<=r;j++)
  112. s[i] = (s[i]+s[i-j]*a[j]%Mod)%Mod;
  113. }
  114. for(i=;i<=r;i++)
  115. res = (res + (s[k-i+]*ans.m[][i])%Mod)%Mod;
  116. printf("%lld\n",res%Mod);
  117. }
  118. }
  119. return ;
  120. }

SPOJ AMR10E Stocks Prediction --二分求和+矩阵快速幂的更多相关文章

  1. 【学术篇】SPOJ GEN Text Generator AC自动机+矩阵快速幂

    还有5天省选才开始点字符串这棵技能树是不是太晚了点... ~题目の传送门~ AC自动机不想讲了QAQ.其实很久以前是学过然后打过板子的, 但也仅限于打过板子了~ 之前莫名其妙学了一个指针版的但是好像不 ...

  2. poj3233 题解 矩阵乘法 矩阵快速幂

    题意:求S = A + A2 + A3 + … + Ak.(mod m) 这道题很明显可以用矩阵乘法,但是这道题的矩阵是分块矩阵, 分块矩阵概念如下:当一个矩阵A中的单位元素aij不是一个数值而是一个 ...

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

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

  4. 2017 ECJTU ACM程序设计竞赛 矩阵快速幂+二分

    矩阵 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission ...

  5. POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)

    题意:求S=(A+A^2+A^3+...+A^k)%m的和 方法一:二分求解S=A+A^2+...+A^k若k为奇数:S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+ ...

  6. BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)

    题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...

  7. POJ3233:Matrix Power Series(矩阵快速幂+二分)

    http://poj.org/problem?id=3233 题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加).输出的数据mod m.k ...

  8. POJ 3233 Matrix Power Series 【经典矩阵快速幂+二分】

    任意门:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K To ...

  9. HDU 4549 (费马小定理+矩阵快速幂+二分快速幂)

    M斐波那契数列 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Statu ...

随机推荐

  1. eclipse优化与标准化记录

    1.文件使用UTF-8格式: 2.取消js验证: 3.设置java文件模板

  2. [js开源组件开发]js手机联动选择地区仿ios 开源git

    js手机联动选择地区 前言:由于网上找到了一个mobiscrool,比较全,但是不开源,只能试用15天,正式版竟然要三千块钱,穷人只能自己动手,写了个只针对弹窗地区选择的. 本站点所有的资源均在git ...

  3. QT5中全屏显示子窗口和取消全屏的方法

    问题描述:用QT5做了个MDI多窗体应用程序,想把子窗体全屏显示,用网上的方法,但总是遇到问题. 网上的解决方法原文在这:http://www.cnblogs.com/Rick-w/archive/2 ...

  4. win7 下配置Openssl

    最近刚刚装了openssl,遇到了很多问题,于是记录了下来: 我的PC环境是:系统win7,32位,Microsoft Visual Studio 2010: 下面开始安装: 1.安装前的准备:首先下 ...

  5. iOS仿京东分类菜单实例实现

    在APP开发过程中此功能还是比较常见的模块,左边为菜单展示,右边为菜单下数据的展示,选择不同的菜单右边的数据源进行更新,此实例主要运用到UITableView,UICollectionView,OC谓 ...

  6. Oracle学习之简单查询

    使用scott用户下的表, 1.查询所有内容SELECT * FROM emp; 2.查询员工信息,包括员工编号,姓名,职位3个信息SELECT empno,ename,job FROM emp; 3 ...

  7. IOS SizeClasses 详解

    SizeClasses 详解 iOS 8在应用界面的可视化设计上添加了一个新的特性-Size Classes.对于任何设备来说,界面的宽度和高度都只分为三种描述:紧凑,任意和宽松.这样开发者便可以无视 ...

  8. .NET下的并行开发

    并行开发一直是程序员在开发项目中遇到的一道坎,但为了迎合硬件的升级,面对高端多核的处理器,并行编程势在必行.在.NET平台下的开发支持并行模式,下面用一个实际项目说明并行的高效率和神奇之处. 在优化中 ...

  9. OC-分类

    1.不能再分类里面添加属性, 只能添加方法. 2.如果在分类里面使用@property,那么他只生成sette,getter的声明而没有实现. 3.如在在分类中写了与本类同名的方法,优先调用分类里面的 ...

  10. 优于CoreData的Realm数据库基础教程

    Realm 是一个跨平台的移动数据库引擎,于 2014 年 7 月发布,准确来说,它是专门为移动应用所设计的数据持久化解决方案之一. Realm 可以轻松地移植到您的项目当中,并且绝大部分常用的功能( ...