E  DZY Loves Fibonacci Numbers

In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation

F1 = 1; F2 = 1; Fn = Fn - 1 + Fn - 2 (n > 2).

DZY loves Fibonacci numbers very much. Today DZY gives you an array consisting of nintegers: a1, a2, ..., an. Moreover, there are m queries, each query has one of the two types:

  1. Format of the query "1 l r". In reply to the query, you need to add Fi - l + 1 to each element ai, where l ≤ i ≤ r.
  2. Format of the query "2 l r". In reply to the query you should output the value of  modulo 1000000009 (109 + 9).

Help DZY reply to all the queries.

Input

The first line of the input contains two integers n and m (1 ≤ n, m ≤ 300000). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — initial array a.

Then, m lines follow. A single line describes a single query in the format given in the statement. It is guaranteed that for each query inequality 1 ≤ l ≤ r ≤ n holds.

Output

For each query of the second type, print the value of the sum on a single line.

Example

Input
4 41 2 3 41 1 42 1 41 2 42 1 3
Output
1712

Note

After the first query, a = [2, 3, 5, 7].

For the second query, sum = 2 + 3 + 5 + 7 = 17.

After the third query, a = [2, 4, 6, 9].

For the fourth query, sum = 2 + 4 + 6 = 12.

题目的大意就是,定义了fib数列前两项F[1]=1,F[2]=1。给出整数n,m,再给出n个数和m项操作。

每个操作包含三个数op,l,r,若op=1,就在[l,r]的区间相应加上F[1,r-l+1](每个数对应着加),若op=2,就将[l,r]中所有数统计和并输出。

首先,我们要知道,fib数列有个特殊的性质_两个fib数列相加,还是fib数列,只是前两项的值变动了而已(从而导致后面的数变动).

那么,根据这个性质,就可以通过累计的方法实现_用线段树进行维护.

首先,我们需要知道一些性质:

设fib[1]=a,fib[2]=b,则fib[n]=fib[n-1]*b+fib[n-2]*a.(可推)

fib[1]+fib[2]+fib[3]+......+fib[n]=fib[n+2]-fib[2].(可推)

通过这两个性质,我们可以巧妙的记录线段树上每一个节点的前两个(fib[1],fib[2])的值,然后计算出这个节点上[L,R],所有数的和.

怎么来?

我们对于每一个线段树上的节点,都记录两个值,ta,tb,分别表示这个区间前两项的值,在更新时,

 void upt(int now,int fir,int sec,int len){
     T[now].ta=(T[now].ta+fir)%TT,T[now].tb=(T[now].tb+sec)%TT;
     T[now].key=((]-(long long)sec)%TT;
 }

其中前两句是将标记累计,最后以句就是顺带计算出这个节点的值.

同时,在pushdown函数中,也要对此进行更新.

 void push_down(int now){
     if (!T[now].ta&&!T[now].tb) return;
     int L=T[now].L,R=T[now].R;
     upt(now<<,T[now].ta,T[now].tb,mid-L+);
     ,a,b;
     a=((]+(long long)T[now].tb*fib[len])%TT;
     b=((])%TT;
     upt(now<<|,a,b,R-mid);
     T[now].ta=T[now].tb=;
 }

其中,对于某个节点的子节点,有两段.一段[L,mid],一段[mid+1,R].

那么更新[L,mid]时,它的前缀和当前节点是一样的,所以不需改动信息,直接下传.

更新[mid+1,R]时,需要重新计算出这段区间前两项的值(这可以用上面说的性质算),然后才能下传.

最后下传完了记得把标记清空.

不过不知道为什么,我的线段树开4,5倍空间会炸,开10倍才不炸,很玄学......

 #include<cstdio>
 #include<cstring>
 #include<algorithm>
 #define mid ((L+R)>>1)
 using namespace std;
 ,maxn=;
 int n,m,a[maxn],fib[maxn];
 ];
 int read(){
     ; char ch=getchar();
     ') ch=getchar();
     +ch-',ch=getchar();
     return x;
 }
 void make(int now,int L,int R){
     T[now].L=L,T[now].R=R;
     if (L==R){T[now].key=a[L]; return;}
     make(now<<,L,mid),make(now<<|,mid+,R);
     T[now].key=(T[now<<].key+T[now<<|].key)%TT;
 }
 void upt(int now,int fir,int sec,int len){
     T[now].ta=(T[now].ta+fir)%TT,T[now].tb=(T[now].tb+sec)%TT;
     T[now].key=((]-(long long)sec)%TT;
 }
 void push_down(int now){
     if (!T[now].ta&&!T[now].tb) return;
     int L=T[now].L,R=T[now].R;
     upt(now<<,T[now].ta,T[now].tb,mid-L+);
     ,a,b;
     a=((]+(long long)T[now].tb*fib[len])%TT;
     b=((])%TT;
     upt(now<<|,a,b,R-mid);
     T[now].ta=T[now].tb=;
 }
 void alter(int now,int aimL,int aimR){
     int L=T[now].L,R=T[now].R;
     if (L>aimR||R<aimL) return;
     ],fib[L-aimL+],R-L+); push_down(now); return;}
     push_down(now);
     alter(now<<,aimL,aimR),alter(now<<|,aimL,aimR);
     T[now].key=(T[now<<].key+T[now<<|].key)%TT;
 }
 int seek(int now,int aimL,int aimR){
     int L=T[now].L,R=T[now].R;
     ;
     if (L>=aimL&&R<=aimR) return T[now].key;
     push_down(now);
     ,aimL,aimR)+seek(now<<|,aimL,aimR))%TT;
 }
 int main(){
     n=read(),m=read(),memset(T,,sizeof T);
     ; i<=n; i++) a[i]=read();
     make(,,n);
     fib[]=,fib[]=fib[]=;
     ; i<=n+; i++) fib[i]=(fib[i-]+fib[i-])%TT;
     ; i<=m; i++){
         int tp=read(),L=read(),R=read();
         ) alter(,L,R);
         ,L,R));
     }
     ;
 }

[CodeForces - 447E] E - DZY Loves Fibonacci Numbers的更多相关文章

  1. codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)(两种方法)

    In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 ...

  2. Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列

    C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...

  3. Codeforces Round #FF 446 C. DZY Loves Fibonacci Numbers

    參考:http://www.cnblogs.com/chanme/p/3843859.html 然后我看到在别人的AC的方法里还有这么一种神方法,他预先设定了一个阈值K,当当前的更新操作数j<K ...

  4. ACM学习历程—Codeforces 446C DZY Loves Fibonacci Numbers(线段树 && 数论)

    Description In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence ...

  5. codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新

    DZY Loves Fibonacci Numbers Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d &a ...

  6. Codeforces 446C —— DZY Loves Fibonacci Numbers(线段树)

    题目:DZY Loves Fibonacci Numbers 题意比較简单,不解释了. 尽管官方的题解也是用线段树,但还利用了二次剩余. 可是我没有想到二次剩余,然后写了个感觉非常复杂度的线段树,还是 ...

  7. 『题解』Codeforces446C DZY Loves Fibonacci Numbers

    更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description In mathematical terms, the sequence \( ...

  8. cf446C DZY Loves Fibonacci Numbers

    C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...

  9. Codeforces446C - DZY Loves Fibonacci Numbers

    Portal Description 给出一个\(n(n\leq3\times10^5)\)个数的序列,进行\(m(m\leq3\times10^5)\)次操作,操作有两种: 给区间\([L,R]\) ...

随机推荐

  1. Gym 101617J Treasure Map(bfs暴力)

    http://codeforces.com/gym/101617/attachments 题意:给出一个图,每个顶点代表一个金矿,每个金矿有g和d两个值,g代表金矿初始的金子量,d是该金矿每天的金子量 ...

  2. 实现一个键对应多个值的字典(multidict)

    一个字典就是一个键对应一个单值的映射.如果你想要一个键映射多个值,那么你就需要将这多个值放到另外的容器中, 比如列表或者集合里面.比如,你可以像下面这样构造这样的字典: d = { , , ], , ...

  3. ubuntu14.04 Keras框架搭建

    >>>sudo su >>> pip3 install -U --pre pip setuptools wheel >>> pip3 instal ...

  4. 1.spring基础知识讲解

    引言:以下记录一些自己在使用时pringle框架时的一些自己心得合成体会时,如有侵权,请联系本博主. 1. spring基本都使用 spring是一个开源的轻量级框架,其目的是用于简化企业级应用程序开 ...

  5. 【汇总】基于.NET平台常用的框架整理

    分布式缓存框架: Microsoft Velocity:微软自家分布式缓存服务框架. Memcahed:一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度. Redis:是一个高性能的K ...

  6. Servlet模板,一个供新手参考的模板

    由于这学期老师的进度是刚开始教JavaSE部分,而我的进度比较快,所以买了3本javaee的书,我根据自己的基础,选择了合适的开发实践,另外两本书都和框架相关,我自认为我的web基础还不是很牢固,所以 ...

  7. ROC与AUC原理

    来自:https://blog.csdn.net/shenxiaoming77/article/details/72627882 来自:https://blog.csdn.net/u010705209 ...

  8. GCD LCM UVA - 11388

    代码很短理解不容易,在这说不清,大家代码里寻真相. 为什么二者相除就可以A了多找点数试试理解理解. #include<stdio.h> #define mod 1000000007 #de ...

  9. MVC数据列表展示【三】

    一.控制器向视图传递参数的两种形式:使用到的技术有EF,linq表达式,StringBuilder,相关技术都可以在我的博客园中找到详细的技术介绍. 1. 第一种是通过字符通过foreach循环拼接将 ...

  10. ISNULL函数的深入讲解

    1.  标题有点夸张 2. 今天做统计查询员工加班时长的时,因为要将NULL值导入到decimal类型的字段中,但是发现导入之后得字段不属于NULL也不等于0,因此在接下来的运算过程中就很难继续进行, ...