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 l r x — increase all integers on the segment from l to r by values x;
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官方题解下面有个评论说的很清楚,大家可以看一下。

代码

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
const int maxn = 1e5+5;
struct node
{
long long a[2][2];
void reset()
{
memset(a,0,sizeof(a));
}
void one()
{
reset();
a[0][0]=a[1][1]=1;
}
};
node add(node A,node B)
{
node k;k.reset();
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
k.a[i][j]=(A.a[i][j]+B.a[i][j])%mod;
return k;
}
node mul(node A,node B)
{
node k;memset(k.a,0,sizeof(k.a));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int t=0;t<2;t++)
k.a[i][j]=(k.a[i][j]+A.a[i][t]*B.a[t][j])%mod;
return k;
}
node qpow(int p)
{
node A;
A.a[0][0]=0,A.a[1][0]=1,A.a[0][1]=1,A.a[1][1]=1;
node K;
K.one();
while(p)
{
if(p%2)K=mul(K,A);
A=mul(A,A);p/=2;
}
return K;
}
typedef node SgTreeDataType;
struct treenode
{
int L , R , flag;
SgTreeDataType sum , lazy;
void update(SgTreeDataType v)
{
sum=mul(sum,v);
lazy=mul(lazy,v);
flag=1;
}
}; treenode tree[maxn*4];
int a[maxn];
inline void push_down(int o)
{
if(tree[o].flag)
{
tree[2*o].update(tree[o].lazy) ; tree[2*o+1].update(tree[o].lazy);
tree[o].flag = 0;tree[o].lazy.one();
}
} inline void push_up(int o)
{
tree[o].sum = add(tree[o*2].sum,tree[o*2+1].sum);
}
node tmp;
inline void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R,tree[o].sum.reset(),tree[o].lazy.one(),tree[o].flag=0;
if(L==R)
{
tree[o].sum=qpow(a[L]);
}
if (R > L)
{
int mid = (L+R) >> 1;
build_tree(L,mid,o*2);
build_tree(mid+1,R,o*2+1);
push_up(o);
}
} inline void update(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) tree[o].update(v);
else
{
push_down(o);
int mid = (L+R)>>1;
if (QL <= mid) update(QL,QR,v,o*2);
if (QR > mid) update(QL,QR,v,o*2+1);
push_up(o);
}
} inline SgTreeDataType query(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].sum;
else
{
push_down(o);
int mid = (L+R)>>1;
SgTreeDataType res;res.reset();
if (QL <= mid) res=add(res,query(QL,QR,2*o));
if (QR > mid) res=add(res,query(QL,QR,2*o+1));
push_up(o);
return res;
}
} int n,q; int main()
{
tmp.a[0][0]=0,tmp.a[1][0]=1,tmp.a[0][1]=1,tmp.a[1][1]=1;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build_tree(1,n,1);
for(int i=1;i<=q;i++)
{
int op;scanf("%d",&op);
if(op==2){
int a,b;scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1).a[1][0]);
}
else{
int a,b,c;scanf("%d%d%d",&a,&b,&c);
update(a,b,qpow(c),1);
}
}
return 0;
}

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. [整理]HTML5 WebSocket

    vs2013 win7 iis7.5貌似不行,查阅了资料,好像得iis8支持 <ASP.NET SignalR系列>第一课 认识SignalR http://www.cnblogs.com ...

  2. [整理]ASP.NET 中异常处理

    [整理]ASP.NET 中异常处理 1.直接通过重写Controller的OnException来处理异常 public class HomeController : Controller { pub ...

  3. Flex 经验笔记二

    向 Module 传递数据:好像只能传递些像 整型,字符型等简单类型的数据,也能传递像 json 这样的 Object 对象,但如果 Object 对象是从层的,其子级数据,好像也读取不到. func ...

  4. 【转】CocoaLumberjack——带颜色的Log

    CHENYILONG Blog [转]CocoaLumberjack--带颜色的Log - 趣味苹果开发 - 博客园 转自:趣味苹果开发   CocoaLumberjack--带颜色的Log Coco ...

  5. camera驱动框架分析(上)

    前言 camera驱动框架涉及到的知识点比较多,特别是camera本身的接口就有很多,有些是直接连接到soc的camif口上的,有些是通过usb接口导出的,如usb camera.我这里主要讨论前者, ...

  6. 使用 CasperJS 构建 Web 爬虫

    转载:https://www.oschina.net/translate/building-your-own-web-scraper-in-nodejs 从你的应用中收集数据有时候可能有点困难和艰辛. ...

  7. 002_CentOS-6.4-x86_64安装包的说明

    http://mirrors.sohu.com/centos/6.6/isos/x86_64/?qq-pf-to=pcqq.group //souhu镜像下载地址 0_README.txt 25-Oc ...

  8. 06 Go 1.6 Release Notes

    Go 1.6 Release Notes Introduction to Go 1.6 Changes to the language Ports Tools Cgo Compiler Toolcha ...

  9. SpringMvc定时器任务

    在最近的工作中,涉及到一个定时任务,由于以前对springMVC使用较少,所以,上网找了一点资料.这个demo感觉挺好,推荐给大家. 使用到的JAR文件: aopalliance-1.0.jarcom ...

  10. Python_oldboy_自动化运维之路_面向对象(十)

    面向对象编程 OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向 ...