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. 5个经典的javascript面试问题

    问题1:Scope作用范围 考虑下面的代码: (function() {   var a = b = 5;})(); console.log(b); 什么会被打印在控制台上? 回答 上面的代码会打印 ...

  2. 20155315 2016-2017-2 《Java程序设计》第七周学习总结

    教材学习内容总结 第12章 Lambda语法 Lambda定义 一个不用被绑定到一个标识符上,并且可能被调用的函数. 在只有Lambda表达式的情况下,参数的类型必须写出来,如果有目标类型的话,在编译 ...

  3. Markdown基础教程

    标题 Markdown支持6种级别的标题,对应html标签 h1 ~ h6

  4. ubuntu16.04 caffe(GPU模式)安装

    历时5天终于完成了,配置中出现了各种各样的Error,这里记录一下,希望能为正在安装的人提供一点帮助. 配置中主要参考博客:http://blog.csdn.net/yhaolpz/article/d ...

  5. C语言清空输入缓冲区的N种方法对比【转】

    转自:http://www.cnblogs.com/codingmylife/archive/2010/04/18/1714954.html C语言中有几个基本输入函数: //获取字符系列 int f ...

  6. 08 Go 1.8 Release Notes

    Go 1.8 Release Notes Introduction to Go 1.8 Changes to the language Ports Known Issues Tools Assembl ...

  7. Database Course Summary 001

    0x01. 基本概念 SQL:Structured English Query Language 1. 数据 Data 数据(Data):描述事物的符号记录:数据内容是事物特性的反应或描述:数据是符号 ...

  8. Laravel中服务提供者和门面模式

    在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel的服务提供者的方式来使用. 这两者其实区别不大,主要是前者使用的话,会跟业务代码产生依赖, ...

  9. 带你走进Android Afinal框架的世界

    1.什么是Afinal框架? Afinal是一个开源的android的orm和ioc应用开发框架,其特点是小巧灵活,代码入侵量少.在android应用开发中,通过Afinal的ioc框架,诸如ui绑定 ...

  10. thinkphp AOP(面向切面编程)

    AOP: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软 ...