CF446C DZY Loves Fibonacci Numbers 万能的线段树
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 }