题目大意:

一个由自然数组成的数列按下式定义:

对于i <= k:ai = bi

对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k

其中bj和 cj (1<=j<=k)是给定的自然数。写一个程序,给定自然数m <= n, 计算am + am+1 + am+2 + ... + an, 并输出它除以给定自然数p的余数的值。

题解

首先显然我们可以构造一个矩阵递推\(a_i\)。

如果直接从m递推到n,会超时(我也没写过,不知道),我们在矩阵中加一维,记录\(s_i\),具体可以见代码

注意一个问题:减法取模时应该加成正数。因为这个WA了好几次。

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define ull unsigned long long
  4. using namespace std;
  5. const ll maxn = 20;
  6. ll k, B[maxn], C[maxn], s[maxn];
  7. ll m, n, p;
  8. struct M {
  9. ll n, m;
  10. ll a[maxn][maxn];
  11. } a, b;
  12. M operator*(M a, M b) {
  13. M c;
  14. c.n = a.n;
  15. c.m = b.m;
  16. memset(c.a, 0, sizeof(c.a));
  17. for (ll i = 1; i <= c.n; i++) {
  18. for (ll j = 1; j <= c.m; j++) {
  19. for (ll k = 1; k <= a.m; k++)
  20. c.a[i][j] = (c.a[i][j] + (ull)(a.a[i][k] * b.a[k][j]) % p) % p;
  21. }
  22. }
  23. return c;
  24. }
  25. M pow(M a, ll b) {
  26. M ret;
  27. ret.n = a.n;
  28. ret.m = a.m;
  29. memset(ret.a, 0, sizeof(ret.a));
  30. for (ll i = 1; i <= ret.n; i++)
  31. ret.a[i][i] = 1;
  32. while (b) {
  33. if (b & 1)
  34. ret = ret * a;
  35. a = a * a;
  36. b >>= 1;
  37. }
  38. return ret;
  39. }
  40. void print(M x) {
  41. for (ll i = 1; i <= x.n; i++) {
  42. for (ll j = 1; j <= x.m; j++)
  43. cout << x.a[i][j] << ' ';
  44. cout << endl;
  45. }
  46. }
  47. ll calc(ll x) {
  48. M y = pow(a, x + 1);
  49. // prll (y);
  50. y = y * b;
  51. return y.a[1][1];
  52. }
  53. int main() {
  54. // freopen("input", "r", stdin);
  55. scanf("%lld", &k);
  56. a.n = k + 1;
  57. a.m = k + 1;
  58. b.n = k + 1;
  59. b.m = 1;
  60. s[0] = 0;
  61. for (ll i = 1; i <= k; i++) {
  62. scanf("%lld", &B[i]);
  63. }
  64. for (ll i = 1; i <= k; i++)
  65. scanf("%lld", &C[i]);
  66. scanf("%lld %lld %lld", &m, &n, &p);
  67. for (ll i = 1; i <= k; i++)
  68. s[i] = (B[i] + s[i - 1]) % p;
  69. b.a[1][1] = s[k - 1];
  70. for (ll i = 1; i <= k; i++)
  71. b.a[i + 1][1] = B[k - i + 1];
  72. a.a[1][1] = a.a[1][2] = 1;
  73. for (ll i = 1; i <= k; i++)
  74. a.a[2][i + 1] = C[i];
  75. for (ll i = 1; i < k; i++)
  76. a.a[i + 2][i + 1] = 1;
  77. // a = a * b;
  78. ll ans1, ans2;
  79. // calc(1);
  80. if (m - 1 > k)
  81. ans1 = calc(m - 1 - k);
  82. else
  83. ans1 = s[m - 1];
  84. if (n > k)
  85. ans2 = calc(n - k);
  86. else
  87. ans2 = s[n];
  88. printf("%lld\n", (ans2 - ans1 + p) % p);
  89. return 0;
  90. }

[bzoj3231][SDOI2008]递归数列——矩阵乘法的更多相关文章

  1. bzoj 3231 [Sdoi2008]递归数列——矩阵乘法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3231 矩阵乘法裸题. 1018是10^18.别忘了开long long. #include& ...

  2. 【bzoj3231】[Sdoi2008]递归数列 矩阵乘法+快速幂

    题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj  ...

  3. [luogu2461 SDOI2008] 递归数列 (矩阵乘法)

    传送门 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai- ...

  4. P2461 [SDOI2008]递归数列 矩阵乘法+构造

    还好$QwQ$ 思路:矩阵快速幂 提交:1次 题解: 如图: 注意$n,m$如果小于$k$就不要快速幂了,直接算就行... #include<cstdio> #include<ios ...

  5. BZOJ3231: [Sdoi2008]递归数列

    BZOJ3231: [Sdoi2008]递归数列 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + ...

  6. BZOJ 3231: [Sdoi2008]递归数列( 矩阵快速幂 )

    矩阵乘法裸题..差分一下然后用矩阵乘法+快速幂就可以了. ----------------------------------------------------------------------- ...

  7. bzoj 3231 [ Sdoi 2008 ] 递归数列 —— 矩阵乘法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3231 裸矩阵乘法. 代码如下: #include<iostream> #incl ...

  8. BZOJ-3231 [SDOI2008]递归数列

    转成矩阵连乘后,矩阵快速幂加速解决. 一开始没把需要longlong的变量补全..而且没初始化2333 #include <cstdlib> #include <cstdio> ...

  9. BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法

    BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1a ...

随机推荐

  1. Objective-C反射机制

    oc反射机制有三个用途: 1.获得Class Class LoginViewController = NSClassFromString(@"LoginViewController" ...

  2. 指纹识别人脸识别 iOS

    //1.判断iOS8及以后的版本 if([UIDevice currentDevice].systemVersion.doubleValue >= 8.0){ //从iPhone5S开始,出现指 ...

  3. 一些可能有点用处的C#开发经验

    前言: 下个月就要去进行Java开发了,以后C#碰的就少了(可惜去年买了三本C#的书,几乎还是全新的……),平时一些经验都记在OneNote里面,现在收集整理出来,因为只能利用交接工作的打酱油的时间, ...

  4. Hackerrank - [Algo] Matrix Rotation

    https://www.hackerrank.com/challenges/matrix-rotation-algo 又是一道耗了两小时以上的题,做完了才想起来,这不就是几年前在POJ上做过的一个同类 ...

  5. C++学习014函数值传递和地址传递

    当我们给一个函数传参数的时候,可以直接值传入函数,也给可以把一个地址传入函数 区别就是一个本身不被改变,而另一本身也在改变, 在开发时候都会用到, 这里做下记录 #include <iostre ...

  6. Android Spiner实现Key-Value

    原网址:http://www.eoeandroid.com/thread-29687-1-1.html?_dsign=02d5cd6a 学习到的方法,直接上代码了: 1.定义一个class publi ...

  7. 0.爬虫 urlib库讲解 urlopen()与Request()

    # 注意一下 是import urllib.request 还是 form urllib import request 0. urlopen() 语法:urllib.request.urlopen(u ...

  8. GraphSAGE 代码解析(三) - aggregators.py

    原创文章-转载请注明出处哦.其他部分内容参见以下链接- GraphSAGE 代码解析(一) - unsupervised_train.py GraphSAGE 代码解析(二) - layers.py ...

  9. hadoop 环境配置

    HADOOP_HOME E:\tool\eclipse\hadoop-2.7.3 HADOOP_USER_NAME ambari-qa path: %HADOOP_HOME%/bin

  10. java设计模式之责任链模式以及在java中作用

    责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个 ...