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. 【NOIP 2016】Day2 T3 愤怒的小鸟

    Problem Description \(Kiana\) 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 \((0,0)\) 处,每次 \(Kiana\ ...

  2. POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)

    http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚 ...

  3. 理解 Redis(1) - Redis 简介

    Redis 的含义 全称: REmote DIctionary Server 远程词典服务器 由于支持 string, list, set, ordered set, hash 等多重数据结构, 因此 ...

  4. ngui项目花屏问题

    项目用的ngui 最近在金立手机上遇到一个问题就是  启动的时候会花一下屏幕 一闪而过  由于ngui默认camera使用的是clear depth  所以按照网上的办法修改 color 跟skybo ...

  5. linq to sql and linq to object 总结

    Enumable类型是linq to object   是一个很特殊的类型   这个类型的数据源都是在程序的内存中 Queryable类型是 Linq to sql   对数据库进行操作都是这个类型  ...

  6. openstack环境搭建常用命令

    1,编辑/etc/selinux/config文件,关闭selinux SELINUX=disabled 2,清空iptables规则并保存 # iptables -F # service iptab ...

  7. WIN7右键在目录当前打开命令行Cmd窗口

    Win7系统大家习惯“Win+R”的组合键打开命令提示符. 2. 通常情况下,我们点击鼠标右键是没有命令行选项的.. 3.在桌面上先按住Shift键,然后鼠标右键,出现选项“在此处打开命令窗口(W)” ...

  8. Linux-Ubuntu16.0.4相关命令

    1.更新软件源 sudo apt-get update 2.shell命令 基本格式:命令  [-选项] [-命令参数] ls #查看当前文件夹下的文件 ls -l XXXX #查看XXXX文件夹下的 ...

  9. 在python中使用正则表达式(三)

    这里主要说一下贪婪匹配和非贪婪匹配  贪婪匹配:匹配尽可能多的字符:  非贪婪匹配:匹配尽可能少的字符 python的正则匹配默认是贪婪匹配 例子: >>> re.match(r'^ ...

  10. xpath是什么(入门教程)

    xpath是什么(入门教程) 一.总结 一句话总结:一句话,XPath 是一门在 XML 文档中查找信息的语言.简单来说,html类似于xml结构,但是没有xml格式那么严格. 在xml中查找信息 包 ...