In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation
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:
- 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.
- 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.
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.
For each query of the second type, print the value of the sum on a single line.
4 4
1 2 3 4
1 1 4
2 1 4
1 2 4
2 1 3
17
12
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 }