题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作

分析:线段树

   线段树的每个节点表示(f[i],f[i-1])这个数组

   因为矩阵的可加性,所以可以进行lazy操作

   我最开始的想法是每个节点lazy表示该区间下标加了多少,add表示该区间已经加的下标对应的矩阵乘积,这样更新lazy是O(1)的,算add是O(logn)的

   但是这样每次pushdown的时候,add下传总要多个log,会TLE

   更好的办法是lazy表示加的下标对应的矩阵乘积,这样虽然每次更新lazy是O(logn)的,但是pushdown的时候就是直接把(f[i],f[i-1])和lazy[2][2]乘起来了,是O(1)的

代码:

  1. #include<bits/stdc++.h>
  2. const int maxn=1e5;
  3. const long long mod=1e9+;
  4. int ch[maxn*+][];
  5. long long sum[maxn*+][],add[maxn*+][][],a[maxn+];
  6. int len=,n,m;
  7. void mer(long long a[][],long long b[][])
  8. {
  9. long long s[][];
  10. memset(s,,sizeof(s));
  11. for(int i=;i<;++i)
  12. for(int j=;j<;++j)
  13. for(int k=;k<;++k)
  14. s[i][j]=(s[i][j]+a[i][k]*b[k][j]%mod)%mod;
  15. for(int i=;i<;++i)
  16. for(int j=;j<;++j)
  17. a[i][j]=s[i][j];
  18. }
  19. void fib(long long num[][],long long x)
  20. {
  21. long long a[][]={{,},{,}};
  22. num[][]=,num[][]=,num[][]=,num[][]=;
  23. while(x)
  24. {
  25. if(x&) mer(num,a);
  26. mer(a,a);
  27. x>>=;
  28. }
  29. }
  30. void cal(long long sum[],long long s[][])
  31. {
  32. long long x=(sum[]*s[][]%mod+sum[]*s[][]%mod)%mod;
  33. long long y=(sum[]*s[][]%mod+sum[]*s[][]%mod)%mod;
  34. sum[]=x,sum[]=y;
  35. }
  36. void pushdown(int k)
  37. {
  38. if(add[k][][]==&&add[k][][]==&&add[k][][]==&&add[k][][]==) return;
  39. //printf("A");
  40. //cal(sum[k],add[k]);
  41. int l=ch[k][],r=ch[k][];
  42. if(l) mer(add[l],add[k]),cal(sum[l],add[k]);
  43. if(r) mer(add[r],add[k]),cal(sum[r],add[k]);
  44. add[k][][]=,add[k][][]=,add[k][][]=,add[k][][]=;
  45. }
  46. void update(int k)
  47. {
  48. int l=ch[k][],r=ch[k][];
  49. //cal(sum[k],add[k]);
  50. //pushdown(k);
  51. for(int i=;i<;++i) sum[k][i]=(sum[l][i]+sum[r][i])%mod;
  52. // if(k==2) printf("A : %d %d %lld %lld\n",l,r,sum[l][0],sum[r][0]);
  53. }
  54. int build(int l,int r)
  55. {
  56. if(l>r) return ;
  57. int mid=(l+r)>>;
  58. int k=++len;
  59. add[k][][]=,add[k][][]=,add[k][][]=,add[k][][]=;
  60. if(l==r)
  61. {
  62. sum[k][]=,sum[k][]=;
  63. long long num[][];
  64. fib(num,a[l]-);
  65. cal(sum[k],num);
  66. //printf("%d %d %d %d %d\n",l,r,k,ch[k][0],ch[k][1]);
  67. return k;
  68. }
  69. ch[k][]=build(l,mid);
  70. ch[k][]=build(mid+,r);
  71. update(k);
  72. return k;
  73. // printf("%d %d %d %d %d\n",l,r,k,ch[k][0],ch[k][1]);
  74. }
  75. void make(int k,int l,int r,int x,int y,long long num[][])
  76. {
  77. if(l>r) return;
  78. if(l>y||r<x) return;
  79. if(x<=l&&y>=r)
  80. {
  81. mer(add[k],num);
  82. cal(sum[k],num);
  83. return;
  84. }
  85. int mid=(l+r)>>;
  86. pushdown(k);
  87. if(l<=mid) make(ch[k][],l,mid,x,y,num);
  88. if(r>mid) make(ch[k][],mid+,r,x,y,num);
  89. update(k);
  90. }
  91. long long query(int k,int l,int r,int x,int y)
  92. {
  93. if(l>r) return ;
  94. if(l>y||r<x) return ;
  95. if(x<=l&&y>=r)
  96. {
  97. return sum[k][];
  98. }
  99. int mid=(l+r)>>;
  100. pushdown(k);
  101. return (query(ch[k][],l,mid,x,y)+query(ch[k][],mid+,r,x,y))%mod;
  102. }
  103. int main()
  104. {
  105.  
  106. scanf("%d %d",&n,&m);
  107. for(int i=;i<=n;++i) scanf("%lld",&a[i]);
  108. build(,n);
  109. //for(int i=1;i<=len;++i) printf("%d %lld %lld\n",i,sum[i][0],sum[i][1]);
  110. //or(int i=1;i<=len;++i) printf("%d %lld %lld %lld %lld\n",i,add[i][0][0],add[i][0][1],add[i][1][0],add[i][1][1]);
  111. for(int i=;i<=m;++i)
  112. {
  113. int t,l,r;
  114. long long x;
  115. scanf("%d %d %d",&t,&l,&r);
  116. if(t==)
  117. {
  118. scanf("%lld",&x);
  119. long long num[][];
  120. fib(num,x);
  121. make(,,n,l,r,num);
  122. }
  123. else printf("%lld\n",query(,,n,l,r));
  124. }
  125. return ;
  126. }

CF719E(线段树+矩阵快速幂)的更多相关文章

  1. Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)

    题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...

  2. 线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E

    http://codeforces.com/contest/719/problem/E 题目大意:给你一串数组a,a[i]表示第i个斐波那契数列,有如下操作 ①对[l,r]区间+一个val ②求出[l ...

  3. CF575A Fibonotci [线段树+矩阵快速幂]

    题意 \(s\{\}\) 是一个循环数列 循环节为 \(n\),你可以改掉 \(m\) 项,这 \(m\) 项独立,且不影响循环节 考虑线段树维护矩阵,单点修改最多m次,每次矩阵快速幂就完事了 // ...

  4. Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]

    /* 题意:给定一个长度为n的序列a. 两种操作: 1.给定区间l r 加上某个数x. 2.查询区间l r sigma(fib(ai)) fib代表斐波那契数列. 思路: 1.矩阵操作,由矩阵快速幂求 ...

  5. 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】

    还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...

  6. 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT

    题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...

  7. 培训补坑(day10:双指针扫描+矩阵快速幂)

    这是一个神奇的课题,其实我觉得用一个词来形容这个算法挺合适的:暴力. 是啊,就是循环+暴力.没什么难的... 先来看一道裸题. 那么对于这道题,显然我们的暴力算法就是枚举区间的左右端点,然后通过前缀和 ...

  8. 【对不同形式矩阵的总结】WC 2009 最短路径问题(线段树+矩阵乘法)

    题意 ​ 题目链接:https://www.luogu.org/problem/P4150 ​ 一个 \(6\times n\) 的网格图,每个格点有一个初始权值.有两种操作: 修改一个格子的权值 求 ...

  9. 【模板】矩阵快速幂 洛谷P2233 [HNOI2002]公交车路线

    P2233 [HNOI2002]公交车路线 题目背景 在长沙城新建的环城公路上一共有8个公交站,分别为A.B.C.D.E.F.G.H.公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另 ...

随机推荐

  1. [Maven]Maven入门教程

    概念 Maven是什么 Maven 是一个项目管理工具.它负责管理项目开发过程中的几乎所有的东西. 版本 maven有自己的版本定义和规则 构建 maven支持许多种的应用程序类型,对于每一种支持的应 ...

  2. Docker for Windows使用简介

    在上一篇文章中,通过演练指导的方式,介绍了在Docker中运行ASP.NET Core Web API应用程序的过程.本文将介绍Docker for Windows的使用. 先决条件 前两周时间,Do ...

  3. JavaScript移除绑定在元素上的匿名事件处理函数

    前言: 面试的时候有点蒙,结束之后想想自己好像根本就误解了面试官的问题,因为我理解的这个问题本身就没有意义.但是当时已经有一些思路,但是在一个点上被卡住. 结束之后脑子瞬间灵光,想出了当时没有迈出的那 ...

  4. oracle函数案例以及分页案例

    --日期函数select sysdate from dual--返回两个日期select months_between(to_date('2017-1-7','yyyy-mm-dd'),to_date ...

  5. 精彩 JavaScript 代码片段

    1. 根据给定的条件在原有的数组上,得到所需要的新数组. ——<JavaScript 王者归来> var a = [-1,-1,1,2,-2,-2,-3,-3,3,-3]; functio ...

  6. [.NET Core].NET Core R2安装教程及Hello示例

    前言 前几天.NET Core发布了.NET Core 1.0.1 R2 预览版,之前想着有时间尝试下.NET Core.由于各种原因,就没有初试.刚好,前几天看到.NET Core发布新版本了,决定 ...

  7. 利用TortoiseSVN获取最新版本的OpenCV源码

    转自: http://blog.csdn.net/vsooda/article/details/7555969 1.下载安装TortoiseSVN:http://tortoisesvn.net/dow ...

  8. PHP数组的基础知识

  9. java反射复制属性值

    /** 将sourceObj的属性拷贝到targetObj * @param sourceObj * @param targetObj * @param clazz 从哪一个类开始(比如sourceO ...

  10. Consul的一个更新:服务端节点故障后重连

    研究了一段时间Consul,想写个攻略来着,但太赖了而且表达能力非正常人...今天发现HashiCorp果然接纳大众意见改了点东西.. 场景是: 假如Consul集群内有三个Server Node 时 ...