[关闭]
@wsndy-xx 2018-05-20T02:48:37.000000Z 字数 1204 阅读 782

Luogu 矩阵加速(数列)

题解


题面



数列的第 项对 取余的值。

由于数据非常大,所以 的递推显然不能满足要求
矩阵加速模板题



解出一个矩阵 使得
显然

考虑得到这样一个矩阵

显然 就是数列的第
由于矩阵乘法满足结合律,所以快速幂计算 即可优化递推的时间复杂度
每次时间复杂度为


Code

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. const int N = 10;
  5. const int Mod = 1e9 + 7;
  6. int n;
  7. struct Node{
  8. long long m[N][N];
  9. Node() {memset(m,0,sizeof m);}
  10. void Clear() {for(int i = 1; i <= 3; i ++) m[i][i] = 1;}
  11. };
  12. Node operator * (const Node & a, const Node & b) {
  13. Node ret;
  14. for(int i = 1; i <= 3; i ++)
  15. for(int j = 1; j <= 3; j ++)
  16. for(int k = 1; k <= 3; k ++)
  17. ret.m[i][j] = (ret.m[i][j] + a.m[i][k] * b.m[k][j] % Mod) % Mod;
  18. return ret;
  19. }
  20. Node Ksm(Node a, int Pow) {
  21. Node ret; ret.Clear();
  22. while(Pow) {
  23. if(Pow & 1) ret = ret * a;
  24. a = a * a;
  25. Pow >>= 1;
  26. }
  27. return ret;
  28. }
  29. int main() {
  30. std:: cin >> n;
  31. for(int i = 1; i <= n; i ++) {
  32. int Pow; std:: cin >> Pow; Pow -= 3;
  33. if(Pow < 1) {std:: cout << 1 <<"\n"; continue ;}
  34. Node A;
  35. A.m[1][1] = 0, A.m[1][2] = 0, A.m[1][3] = 1;
  36. A.m[2][1] = 1, A.m[2][2] = 0, A.m[2][3] = 0;
  37. A.m[3][1] = 0, A.m[3][2] = 1, A.m[3][3] = 1;
  38. Node B = Ksm(A, Pow);
  39. Node Ans;
  40. Ans.m[1][1] = Ans.m[1][2] = Ans.m[1][3] = 1;
  41. Ans = Ans * B;
  42. std:: cout << Ans.m[1][3] << "\n";
  43. }
  44. return 0;
  45. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注