CF446C 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 n integers: a1, a2, ..., an. Moreover, there are mqueries, each query has one of the two types:

  1. Format of the query "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 "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.

Sample test(s)
input
4 4
1 2 3 4
1 1 4
2 1 4
1 2 4
2 1 3
output
17
12
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数列相加还是fib数列,可以通过维护这个区间的fib前两项来做区间加法。

 1 #include <cmath>
 2 #include <queue>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <algorithm>
 7 #define ll long long
 8 using namespace std;
 9 const int inf = 0x3f3f3f3f;
10 const int maxn = 300005;
11 const int mod = 1e9+9;
12 ll t[maxn<<2], f[maxn], num[maxn];
13 int lazyl[maxn<<2], lazyr[maxn<<2];
14 void update(int x, int l, int r, int a, int b, int c, int d);
15 int fib(int a, int b, int n)//求f(0)=a,f(1)=b的斐波那契数列第n项
16 {
17     if (n==0) return a;
18     if (n==1) return b;
19     return (a*f[n-1]%mod+b*f[n]%mod)%mod;
20 }
21 void build(int x, int l, int r)
22 {
23     lazyl[x]=lazyr[x]=0;
24     if (l==r) {
25         t[x]=num[l];
26         return ;
27     }
28     int mid=(l+r)/2;
29     build(x<<1, l, mid);
30     build(x<<1|1, mid+1, r);
31     t[x]=(t[x<<1]+t[x<<1|1])%mod;
32 }
33 void push_down(int x, int l, int r)
34 {
35     int mid=(l+r)/2;
36     if (lazyl[x]||lazyr[x]) {
37         update(x<<1, l, mid, l, r, lazyl[x], lazyr[x]);
38         update(x<<1|1, mid+1, r, l, r, lazyl[x], lazyr[x]);
39         lazyl[x]=0;
40         lazyr[x]=0;
41     }
42 }
43 void update(int x, int l, int r, int a, int b, int c, int d)
44 {
45     if (a<=l&&b>=r) {
46         int nc, nd;
47         nc=fib(c, d, l-a);
48         nd=fib(c, d, l-a+1);
49         c=nc; d=nd;
50         lazyl[x]=(lazyl[x]+c)%mod; lazyr[x]=(d+lazyr[x])%mod;
51         t[x]=(t[x]+fib(c, d, r-l+2)-d)%mod;//f(0)=a,f(1)=b的前n项和∑f(i),i<n,等于f(n+1)-b
52         return ;
53     }
54     push_down(x, l, r);
55     int mid=(l+r)/2;
56     if (a<=mid) update(x<<1, l, mid, a, b, c, d);
57     if (b>mid) update(x<<1|1, mid+1, r, a, b, c, d);
58     t[x]=(t[x<<1]+t[x<<1|1])%mod;
59 }
60 ll query(int x, int l, int r, int a, int b)
61 {
62     if (a<=l&&b>=r) return t[x];
63     push_down(x, l, r);
64     int mid=(l+r)/2;
65     ll ret=0;
66     if (a<=mid) ret+=query(x<<1, l, mid, a, b);
67     if (b>mid) ret+=query(x<<1|1, mid+1, r, a, b);
68     return ret;
69 }
70 int main() {
71     int n, m, op, l, r;
72     f[1]=f[2]=1;
73     scanf("%d%d", &n, &m);
74     for (int i=1; i<=n; i++) {
75         scanf("%I64d", &num[i]);
76     }
77     for (int i=3; i<n+5; i++)
78         f[i]=(f[i-1]+f[i-2])%mod;
79     build(1, 1, n);
80     while (m--) {
81         scanf("%d%d%d", &op, &l, &r);
82         if (op==1) {
83             update(1, 1, n, l, r, 1, 1);
84         } else {
85             printf("%I64d\n", (query(1, 1, n, l, r)%mod+mod)%mod);
86         }
87     }
88     return 0;
89 }
View Code

 

posted @ 2014-07-14 10:33  BlueMandora  阅读(558)  评论(0编辑  收藏  举报