Description

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

  1. \(1\space l \space r\space x\) 表示将数列中的\(a_{l},a_{l+1}...a_{r-1},a_{r}\)加上\(x\)
  2. \(2\space l\space r\) 表示要你求出\(\sum_{i=l}^{r}fib(a_{i})\)对\(10^9+7\)取模后的结果

fib(x)fib(x)表示的是斐波那契的第\(x\)项,\(fib(1)=1,fib(2)=1,fib(i)=fib(i-1)+fib(i-2)(i>2)\)

线段树维护矩阵。

emmm,吓人。

看着题解码

有些懵逼这种矩乘写法。

为啥最普通的矩阵乘法不行???

调了半天发现快速幂里面的\(for\)后面加了个分号??

区间修改操作即为原矩阵乘上转移矩阵的\(x\)次方。

话说和我推的式子貌似又不是很一样???QwQ?

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #define int long long
  5. #define R register
  6. using namespace std;
  7. const int mod=1e9+7;
  8. const int gz=100001;
  9. inline void in(R int &x)
  10. {
  11. int f=1;x=0;char s=getchar();
  12. while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
  13. while(isdigit(s)){x=x*10+s-'0';s=getchar();}
  14. x*=f;
  15. }
  16. int n,m,val[gz];
  17. struct Matrix
  18. {
  19. int m[4][4];
  20. inline void clear()
  21. {
  22. for(R int i=0;i<4;i++)
  23. for(R int j=0;j<4;j++)
  24. m[i][j]=0;
  25. }
  26. inline void pre()
  27. {
  28. for(R int i=0;i<4;i++)m[i][i]=1;
  29. }
  30. inline bool emp()
  31. {
  32. return (m[1][1]==1 and m[1][2]==0 and m[2][1]==0 and m[2][2]==1);
  33. }
  34. Matrix operator *(const Matrix &a)const
  35. {
  36. Matrix tmp;tmp.clear();
  37. for(R int i=1;i<=2;i++)
  38. for(R int k=1;k<=2;k++)
  39. for(R int j=1;j<=2;j++)
  40. tmp.m[i][j]=(tmp.m[i][j]+m[i][k]*a.m[k][j])%mod;
  41. return tmp;
  42. }
  43. friend Matrix operator +(Matrix a,Matrix b)
  44. {
  45. Matrix tmp;tmp.clear();
  46. for(R int i=1;i<=2;i++)
  47. for(R int j=1;j<=2;j++)
  48. tmp.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
  49. return tmp;
  50. }
  51. };
  52. Matrix fir,fb;
  53. Matrix tr[gz<<2],tg[gz<<2];
  54. #define ls o<<1
  55. #define rs o<<1|1
  56. inline void up(R int o)
  57. {
  58. tr[o]=tr[ls]+tr[rs];
  59. }
  60. inline Matrix ksm(R Matrix a,R int y)
  61. {
  62. Matrix res;res.clear();res.pre();
  63. for(;y;y>>=1,a=a*a)
  64. if(y&1)res=res*a;
  65. return res;
  66. }
  67. void build(R int o,R int l,R int r)
  68. {
  69. tr[o].clear();tg[o].clear();tg[o].pre();
  70. if(l==r)
  71. {
  72. tr[o]=fir*ksm(fb,val[l]-1);
  73. return ;
  74. }
  75. R int mid=(l+r)>>1;
  76. build(ls,l,mid);
  77. build(rs,mid+1,r);
  78. up(o);
  79. }
  80. inline void down(R int o)
  81. {
  82. if(tg[o].emp())return;
  83. tr[ls]=tr[ls]*tg[o];
  84. tr[rs]=tr[rs]*tg[o];
  85. tg[ls]=tg[ls]*tg[o];
  86. tg[rs]=tg[rs]*tg[o];
  87. tg[o].clear();
  88. tg[o].pre();
  89. }
  90. void change(R int o,R int l,R int r,R int x,R int y,R Matrix k)
  91. {
  92. if(x<=l and y>=r)
  93. {
  94. tr[o]=tr[o]*k;
  95. tg[o]=tg[o]*k;
  96. return;
  97. }
  98. down(o);
  99. R int mid=(l+r)>>1;
  100. if(x<=mid) change(ls,l,mid,x,y,k);
  101. if(y>mid)change(rs,mid+1,r,x,y,k);
  102. up(o);
  103. }
  104. inline Matrix query(R int o,R int l,R int r ,R int x,R int y)
  105. {
  106. if(x<=l and y>=r)return tr[o];
  107. down(o);
  108. Matrix res;res.clear();
  109. R int mid=(l+r)>>1;
  110. if(x<=mid) res=res+query(ls,l,mid,x,y);
  111. if(y>mid) res=res+query(rs,mid+1,r,x,y);
  112. return res;
  113. }
  114. signed main()
  115. {
  116. fb.clear(),fir.clear();
  117. fir.m[1][1]=fir.m[1][2]=1;fir.m[2][1]=fir.m[2][2]=0;
  118. fb.m[1][1]=fb.m[1][2]=fb.m[2][1]=1;fb.m[2][2]=0;//转移矩阵
  119. in(n),in(m);
  120. for(R int i=1;i<=n;i++)in(val[i]);
  121. build(1,1,n);
  122. for(R int opt,l,r,x;m;m--)
  123. {
  124. in(opt);
  125. switch(opt)
  126. {
  127. case 1:in(l),in(r),in(x);change(1,1,n,l,r,ksm(fb,x));break;
  128. case 2:in(l),in(r),printf("%lld\n",query(1,1,n,l,r).m[1][2]%mod);break;
  129. }
  130. }
  131. }

线段树维护矩阵【CF718C】 Sasha and Array的更多相关文章

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

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

  2. 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 ...

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

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

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

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

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

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

  6. Codeforces 719E (线段树教做人系列) 线段树维护矩阵

    题面简洁明了,一看就懂 做了这个题之后,才知道怎么用线段树维护递推式.递推式的递推过程可以看作两个矩阵相乘,假设矩阵A是初始值矩阵,矩阵B是变换矩阵,求第n项相当于把矩阵B乘了n - 1次. 那么我们 ...

  7. HDU 6155 Subsequence Count 线段树维护矩阵

    Subsequence Count Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Oth ...

  8. DP+线段树维护矩阵(2019牛客暑期多校训练营(第二场))--MAZE

    题意:https://ac.nowcoder.com/acm/contest/882/E 给你01矩阵,有两种操作:1是把一个位置0变1.1变0,2是问你从第一行i开始,到最后一行j有几种走法.你只能 ...

  9. CF719E. Sasha and Array [线段树维护矩阵]

    CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...

随机推荐

  1. C#IList 取区间数据

    items.skip(5).Take(5).ToList() 如取 从 5索引开始 取5条 注意,需要引用using System.Linq;

  2. Spring源码解析-基于注解依赖注入

    在spring2.5版本提供了注解的依赖注入功能,可以减少对xml配置. 主要使用的是 AnnotationConfigApplicationContext: 一个注解配置上下文 AutowiredA ...

  3. bulk_insert_buffer_size and InnoDB

    Q: I read the following on this page http://dev.mysql.com/doc/mysql/en/server-system-variables.html ...

  4. [bzoj 2733]启发式合并权值线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 平衡树待学习.从一个博客学到了合并权值线段树的姿势:http://blog.csdn ...

  5. -webkit-overflow-scrolling:touch;

    -webkit-overflow-scrolling建了带有硬件加速的系统级控件,所以效率很高.但是这相对是耗更多内存的,最好在产生了非常大面积的overflow时才应用. 而且在 ios8  里有b ...

  6. Lesson 2

    周末重新学习了一下java,有了些新的体会 1.关于jdk, jre,and  JVM: Jdk: java development kit,面向开发人员的java开发工具包 Jre:java run ...

  7. 51nod 1791 合法括号子段

    有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列. 合法括号序列的定义是: 1.空序列是合法括号序列. 2.如果S是合法括号序列,那么(S)是合法括号序列.3.如果A和B都是合法括号序列, ...

  8. openstack中region、az、host aggregate、cell 概念

    1. region 更像是一个地理上的概念,每个region有自己独立的endpoint,regions之间完全隔离,但是多个regions之间共享同一个keystone和dashboard.(注:目 ...

  9. 卡片选项页面 JTabbedPane 的使用

    package first; import javax.swing.*; import java.awt.*; import java.awt.event.*; class TtpDemo exten ...

  10. 手机端的META

    一.天猫 <title>天猫触屏版</title> <meta content="text/html; charset=utf-8" http-equ ...