E. Sasha and Array

题目连接:

http://codeforces.com/contest/719/problem/E

Description

Sasha has an array of integers a1, a2, ..., an. You have to perform m queries. There might be queries of two types:

  1. 1 l r x increase all integers on the segment from l to r by values x;
  2. 2 l r find , where f(x) is the x-th Fibonacci number. As this number may be large, you only have to find it modulo 109 + 7.

In this problem we define Fibonacci numbers as follows: f(1) = 1, f(2) = 1, f(x) = f(x - 1) + f(x - 2) for all x > 2.

Sasha is a very talented boy and he managed to perform all queries in five seconds. Will you be able to write the program that performs as well as Sasha?

Input

The first line of the input contains two integers n and m (1 ≤ n ≤ 100 000, 1 ≤ m ≤ 100 000) — the number of elements in the array and the number of queries respectively.

The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109).

Then follow m lines with queries descriptions. Each of them contains integers tpi, li, ri and may be xi (1 ≤ tpi ≤ 2, 1 ≤ li ≤ ri ≤ n, 1 ≤ xi ≤ 109). Here tpi = 1 corresponds to the queries of the first type and tpi corresponds to the queries of the second type.

It's guaranteed that the input will contains at least one query of the second type.

Output

For each query of the second type print the answer modulo 109 + 7.

Sample Input

5 4

1 1 2 1 1

2 1 5

1 2 4 2

2 2 4

2 1 5

Sample Output

5

7

9

Hint

题意

给你n个数,两个操作,1是区间增加x,2是查询区间fib(a[i])的和

题解:

回忆一下你怎么做矩阵快速幂fib的,就知道这个更新,其实就是多乘上了一个A^x矩阵。

A = 【0,1;0,0;】这个玩意儿。

然后就可以区间更新呢。

CF官方题解下面有个评论说的很清楚,大家可以看一下。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int mod = 1e9+7;
  4. const int maxn = 1e5+5;
  5. struct node
  6. {
  7. long long a[2][2];
  8. void reset()
  9. {
  10. memset(a,0,sizeof(a));
  11. }
  12. void one()
  13. {
  14. reset();
  15. a[0][0]=a[1][1]=1;
  16. }
  17. };
  18. node add(node A,node B)
  19. {
  20. node k;k.reset();
  21. for(int i=0;i<2;i++)
  22. for(int j=0;j<2;j++)
  23. k.a[i][j]=(A.a[i][j]+B.a[i][j])%mod;
  24. return k;
  25. }
  26. node mul(node A,node B)
  27. {
  28. node k;memset(k.a,0,sizeof(k.a));
  29. for(int i=0;i<2;i++)
  30. for(int j=0;j<2;j++)
  31. for(int t=0;t<2;t++)
  32. k.a[i][j]=(k.a[i][j]+A.a[i][t]*B.a[t][j])%mod;
  33. return k;
  34. }
  35. node qpow(int p)
  36. {
  37. node A;
  38. A.a[0][0]=0,A.a[1][0]=1,A.a[0][1]=1,A.a[1][1]=1;
  39. node K;
  40. K.one();
  41. while(p)
  42. {
  43. if(p%2)K=mul(K,A);
  44. A=mul(A,A);p/=2;
  45. }
  46. return K;
  47. }
  48. typedef node SgTreeDataType;
  49. struct treenode
  50. {
  51. int L , R , flag;
  52. SgTreeDataType sum , lazy;
  53. void update(SgTreeDataType v)
  54. {
  55. sum=mul(sum,v);
  56. lazy=mul(lazy,v);
  57. flag=1;
  58. }
  59. };
  60. treenode tree[maxn*4];
  61. int a[maxn];
  62. inline void push_down(int o)
  63. {
  64. if(tree[o].flag)
  65. {
  66. tree[2*o].update(tree[o].lazy) ; tree[2*o+1].update(tree[o].lazy);
  67. tree[o].flag = 0;tree[o].lazy.one();
  68. }
  69. }
  70. inline void push_up(int o)
  71. {
  72. tree[o].sum = add(tree[o*2].sum,tree[o*2+1].sum);
  73. }
  74. node tmp;
  75. inline void build_tree(int L , int R , int o)
  76. {
  77. tree[o].L = L , tree[o].R = R,tree[o].sum.reset(),tree[o].lazy.one(),tree[o].flag=0;
  78. if(L==R)
  79. {
  80. tree[o].sum=qpow(a[L]);
  81. }
  82. if (R > L)
  83. {
  84. int mid = (L+R) >> 1;
  85. build_tree(L,mid,o*2);
  86. build_tree(mid+1,R,o*2+1);
  87. push_up(o);
  88. }
  89. }
  90. inline void update(int QL,int QR,SgTreeDataType v,int o)
  91. {
  92. int L = tree[o].L , R = tree[o].R;
  93. if (QL <= L && R <= QR) tree[o].update(v);
  94. else
  95. {
  96. push_down(o);
  97. int mid = (L+R)>>1;
  98. if (QL <= mid) update(QL,QR,v,o*2);
  99. if (QR > mid) update(QL,QR,v,o*2+1);
  100. push_up(o);
  101. }
  102. }
  103. inline SgTreeDataType query(int QL,int QR,int o)
  104. {
  105. int L = tree[o].L , R = tree[o].R;
  106. if (QL <= L && R <= QR) return tree[o].sum;
  107. else
  108. {
  109. push_down(o);
  110. int mid = (L+R)>>1;
  111. SgTreeDataType res;res.reset();
  112. if (QL <= mid) res=add(res,query(QL,QR,2*o));
  113. if (QR > mid) res=add(res,query(QL,QR,2*o+1));
  114. push_up(o);
  115. return res;
  116. }
  117. }
  118. int n,q;
  119. int main()
  120. {
  121. tmp.a[0][0]=0,tmp.a[1][0]=1,tmp.a[0][1]=1,tmp.a[1][1]=1;
  122. scanf("%d%d",&n,&q);
  123. for(int i=1;i<=n;i++)scanf("%d",&a[i]);
  124. build_tree(1,n,1);
  125. for(int i=1;i<=q;i++)
  126. {
  127. int op;scanf("%d",&op);
  128. if(op==2){
  129. int a,b;scanf("%d%d",&a,&b);
  130. printf("%lld\n",query(a,b,1).a[1][0]);
  131. }
  132. else{
  133. int a,b,c;scanf("%d%d%d",&a,&b,&c);
  134. update(a,b,qpow(c),1);
  135. }
  136. }
  137. return 0;
  138. }

Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵的更多相关文章

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

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

  2. Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)

    题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...

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

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

  4. Codeforces Round #373 (Div. 2) E. Sasha and Array

    题目链接 分析:矩阵快速幂+线段树 斐波那契数列的计算是矩阵快速幂的模板题,这个也没什么很多好解释的,学了矩阵快速幂应该就知道的东西= =这道题比较巧妙的在于需要用线段树来维护矩阵,达到快速查询区间斐 ...

  5. Codeforces Round #374 (Div. 2) D. Maxim and Array 线段树+贪心

    D. Maxim and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树

    E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...

  7. Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)

    链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...

  8. Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树

    C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...

  9. Codeforces Round #254 (Div. 1) C. DZY Loves Colors 线段树

    题目链接: http://codeforces.com/problemset/problem/444/C J. DZY Loves Colors time limit per test:2 secon ...

随机推荐

  1. 2018年11月25日ICPC焦作站参赛总结

    可能就这么退役了吧. 对这次ICPC还是比较有信心的,毕竟心态都放平和了. 路途很波折,热身赛还是赶上了. 等到了正赛的时候,开场看出了A题的签到,签到肯定是我来签的,11分钟签完了这道题之后,开始看 ...

  2. php-fpm的status可以查看汇总信息和详细信息

    nginx.conf 配置文件 server { listen ; server_name localhost; index index.php index.html; root /home/tiny ...

  3. mybatis多对多关联查询——(十)

    1.需求 查询用户及用户购买商品信息. 2     sql语句 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表: orders.orderdetail. ...

  4. flask基础之session原理详解(十)

    前言 flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活 ...

  5. 基于 Apache 在本地配置多个虚拟主机

    如何使用 Apache 在本地配置出多个虚拟主机呢?而且使用不同的“域名”来访问本地不同的站点呢? 一般情况下,咱们都使用 localhost 来访问本机上的服务器,在我们的 C:/WINDOWS/s ...

  6. idea项目左边栏只能看到文件看不到项目结构

    1.点击file->project structure..->Modules 点击右上角+加号 ->import Modules 2.选择你的项目,点击确定 3.在如下页面选择imp ...

  7. 在内部局域网内搭建HTTPs

    在内部局域网内搭建HTTPs 配置环境 Windows版本:Windows Server 2008 R2 Standard Service Pack 1 系统类型:       64 位操作系统 内存 ...

  8. js中的事件委托或是事件代理详解(转载)

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  9. linux install weblogic

    一.安装文件 wls1036_generic.jar        weblogic   通用版本 jrockit-jdk1.6.0_45-R28.2.7-4.1.0-linux-x64    jdk ...

  10. ERP渠道文档管理(二十四)

    基本需求: 用例图: 存储过程: CREATE PROCEDURE [dbo].[BioErpCrmChannelDocument_ADD] @DocumentID int, @ChannelID i ...