CF719E. Sasha and Array

题意:

对长度为 n 的数列进行 m 次操作, 操作为:

  1. a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9
  2. 求 F[a[l]]+F[a[l+1]]+...F[a[r]] mod 1e9+7 的余数

矩阵快速幂求斐波那契

矩阵满足乘法分配律和结合律!

所以可以每个节点维护矩阵/矩阵和,区间加相当于区间乘矩阵

注意:不要把快速幂写在里面,复杂度平添一个log。把\(B^C\)算出来之后传进去就好了

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. using namespace std;
  6. typedef long long ll;
  7. #define lc x<<1
  8. #define rc x<<1|1
  9. #define mid ((l+r)>>1)
  10. #define lson lc, l, mid
  11. #define rson rc, mid+1, r
  12. const int N = 1e5+5, P = 1e9+7;
  13. int n, m;
  14. struct Matrix {
  15. ll a[2][2];
  16. ll* operator [](int x) {return a[x];}
  17. Matrix(int p=0) {
  18. if(!p) a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0;
  19. else a[0][0] = a[1][1] = 1, a[0][1] = a[1][0] = 0;
  20. }
  21. } B;
  22. Matrix operator + (Matrix a, Matrix b) {
  23. Matrix c;
  24. for(int i=0; i<2; i++)
  25. for(int j=0; j<2; j++)
  26. c[i][j] = (a[i][j] + b[i][j]) %P;
  27. return c;
  28. }
  29. Matrix operator * (Matrix a, Matrix b) {
  30. Matrix c;
  31. for(int i=0; i<2; i++)
  32. for(int j=0; j<2; j++) {
  33. ll &x = c[i][j];
  34. for(int k=0; k<2; k++)
  35. x = (x + a[i][k] * b[k][j] %P) %P;
  36. }
  37. return c;
  38. }
  39. Matrix operator ^ (Matrix a, int b) {
  40. Matrix ans(1);
  41. ans[0][0] = ans[1][1] = 1;
  42. for(; b; b>>=1, a=a*a)
  43. if(b & 1) ans = ans*a;
  44. return ans;
  45. }
  46. struct meow {
  47. Matrix f;
  48. Matrix v;
  49. int c;
  50. meow() {f[0][0] = 1; v[0][0] = v[1][1] = 1;}
  51. } t[N<<2];
  52. void paint(int x, int l, int r, int d, Matrix &v) {
  53. t[x].c += d;
  54. t[x].v = v * t[x].v;
  55. t[x].f = v * t[x].f;
  56. }
  57. void push_down(int x, int l, int r) {
  58. if(t[x].c) {
  59. paint(lson, t[x].c, t[x].v);
  60. paint(rson, t[x].c, t[x].v);
  61. t[x].c = 0;
  62. t[x].v = Matrix(1);
  63. }
  64. }
  65. void merge(int x) {
  66. t[x].f = t[lc].f + t[rc].f;
  67. }
  68. void build(int x, int l, int r) {
  69. if(l == r) {
  70. cin >> t[x].c;
  71. if(t[x].c > 1) t[x].f = (B ^ (t[x].c - 1)) * t[x].f;
  72. } else {
  73. build(lson);
  74. build(rson);
  75. merge(x);
  76. }
  77. }
  78. void Add(int x, int l, int r, int ql, int qr, int d, Matrix &v) {
  79. if(ql <= l && r <= qr) paint(x, l, r, d, v);
  80. else {
  81. push_down(x, l, r);
  82. if(ql <= mid) Add(lson, ql, qr, d, v);
  83. if(mid < qr) Add(rson, ql, qr, d,v );
  84. merge(x);
  85. }
  86. }
  87. ll Que(int x, int l, int r, int ql, int qr) {
  88. if(ql <= l && r <= qr) return t[x].f[0][0];
  89. else {
  90. push_down(x, l, r);
  91. ll ans = 0;
  92. if(ql <= mid) ans = (ans + Que(lson, ql, qr)) %P;
  93. if(mid < qr) ans = (ans + Que(rson, ql, qr)) %P;
  94. return ans;
  95. }
  96. }
  97. int main() {
  98. //freopen("in", "r", stdin);
  99. ios::sync_with_stdio(false); cin.tie(); cout.tie();
  100. B[0][0] = B[0][1] = B[1][0] = 1;
  101. cin >> n >> m;
  102. build(1, 1, n);
  103. for(int i=1; i<=m; i++) {
  104. int tp, l, r, x;
  105. cin >> tp >> l >> r;
  106. if(tp == 1) {
  107. cin >> x;
  108. Matrix t = B^x;
  109. Add(1, 1, n, l, r, x, t);
  110. } else cout << Que(1, 1, n, l, r) << '\n';
  111. }

CF719E. Sasha and Array [线段树维护矩阵]的更多相关文章

  1. Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵

    E. Sasha and Array 题目连接: http://codeforces.com/contest/719/problem/E Description Sasha has an array ...

  2. 线段树维护矩阵【CF718C】 Sasha and Array

    Description 有一个长为\(n\)的数列\(a_{1},a_{2}...a_{n}\),你需要对这个数列维护如下两种操作: \(1\space l \space r\space x\) 表示 ...

  3. CF718C Sasha and Array(线段树维护矩阵)

    题解 (不会矩阵加速的先去学矩阵加速) 反正我想不到线段树维护矩阵.我太菜了. 我们在线段树上维护一个区间的斐波那契的列矩阵的和. 然后询问时提取每个符合题意列矩阵的答案项(不是列矩阵存了两项吗,一个 ...

  4. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  5. Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵

    Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries ...

  6. hdu 5068 线段树维护矩阵乘积

    http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...

  7. Codeforces 1368H - Breadboard Capacity(最小割+线段树维护矩阵乘法)

    Easy version:Codeforces 题面传送门 & 洛谷题面传送门 Hard version:Codeforces 题面传送门 & 洛谷题面传送门 首先看到这种从某一种颜色 ...

  8. Codeforces 750E - New Year and Old Subsequence(线段树维护矩阵乘法,板子题)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 我做这道 *2600 的动力是 wjz 出了道这个套路的题,而我连起码的思路都没有,wtcl/kk 首先考虑怎样对某个固定的串计 ...

  9. CF718C Sasha and Array 线段树 + 矩阵乘法

    有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$   直接求不好求,改成矩阵乘法的形式:  $a_{i}=M^x\times ...

随机推荐

  1. JS 获取本月第一天零点时间戳并转化成yy-mm-dd

    JS 获取本月第一天零点时间戳并转化成yy-mm-dd 格式 <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  2. python 单例实现

    class View: _instance = None def __new__(cls, *args, **kwargs): if cls._instance is None: cls._insta ...

  3. Oracle问题整合

    1.安装Oracle和ado.net连接Oracle 在“环境变量”的“系统变量”中[必须添加]: ORACLE_HOME = C:\instantclient_11_2 TNS_ADMIN = C: ...

  4. 程序到CPU的路径

    汇编 源码->编译->CPU C/C++ 源码->编译->机器码->系统(执行)->CPU Java/.NET 源码->编译->J字节码->虚拟机 ...

  5. kaldi通用底层矩阵运算库——CUDA

    cudamatrix/cublas-wrappers.h 该头文件对cuBLAS的接口进行了简单的封装(函数名的简化和部分kaldi函数的封装). 比如 cublasSgemm_v2封装为cublas ...

  6. SQL server 数据库中插入中文变???格式乱码的问题另一种容易忽略的情况(C#操作dapper)

    1.先查查 VS2015 中的XXX.cs页面中编码格式,记事本打开另存一下,编码格式可能是ANSI改为unioncode. (中文前面加N或者改排序规则解决不了的情况有可能是以上原因.)

  7. HDU - 1036

    题意描述很垃圾,后来看别人代码才知道怎么回事:对(题目所给d/总时间:所有时间加起来)四舍五入并取整,然后对结果/60得到用了几分钟:对结果%60得到用了几秒. presentation error一 ...

  8. 微信中音乐播放在ios不能自动播放解决

    在微信中,ios手机下面音乐被自动禁掉无法自动播放,我们可以执行触发body上的元素,自动进行播放. //音乐 var x = document.getElementById("myAudi ...

  9. 题解-BJOI2019 光线

    Problem loj3093 & x谷 题意概要:给定 \(n\) 块玻璃,每块玻璃有其折射比例与反射比例(折射比例+反射比例 不一定为 \(100\%\)),求从最上头打下一束光,有多少比 ...

  10. oracle,mysql,sql server三大数据库的事务隔离级别查看方法

    1:mysql的事务隔离级别查看方法 mysql 最简单,执行这条语句就行:select @@tx_isolation  详情: 1.查看当前会话隔离级别 select @@tx_isolation; ...