Description
In mathematical terms, the sequence F n of Fibonacci numbers is defined by the recurrence relation
F 1 = 1; F 2 = 1; F n = F n - 1 + F n - 2 (n > 2).
DZY loves Fibonacci numbers very much. Today DZY gives you an array consisting of n integers: a 1, a 2, …, a n. Moreover, there are m queries, each query has one of the two types:
Format of the query “1 l r”. In reply to the query, you need to add F i - l + 1 to each element a i, 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.
Input
The first line of the input contains two integers n and m (1 ≤ n, m ≤ 300000). The second line contains n integers a 1, a 2, …, a n (1 ≤ a i ≤ 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.
Examples
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.
Solution
设
h
[
1
]
=
a
,
h
[
2
]
=
b
,
h
[
i
]
=
h
[
i
−
1
]
+
h
[
i
−
2
]
(
i
>
2
)
h[1] = a , h[2] = b, ~h[i] = h[i-1] + h[i-2] (i > 2)
h[1]=a,h[2]=b, h[i]=h[i−1]+h[i−2](i>2), 且称 h 这类数列为类Fibonacci数列
有如下结论:
① h的任意长度相同的两段相加后仍为类Fibonacci数列
②
h
[
i
]
=
a
∗
f
[
i
−
2
]
+
b
∗
f
[
i
−
1
]
(
i
>
2
)
(
f
[
i
]
为
F
i
b
o
n
a
c
c
i
数
列
)
h[i] = a * f[i-2] + b * f[i-1] (i > 2) (f[i] 为Fibonacci数列)
h[i]=a∗f[i−2]+b∗f[i−1](i>2)(f[i]为Fibonacci数列)
③
∑
i
=
1
n
h
[
2
]
=
h
[
n
+
2
]
−
h
[
2
]
(
i
>
2
)
\sum ^{n}_{i=1}h\left[ 2\right] =h\left[ n+2\right] -h\left[ 2\right] (i > 2)
∑i=1nh[2]=h[n+2]−h[2](i>2)
手算一下即可得到上述结论
于是我们可以通过维护区间的第一项a和第二项b(做为lazy标记),维护加在该区间上的类Fibonacci数列
Code
#include <bits/stdc++.h>
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
typedef long long ll;
const int mod = 1e9 + 9;
struct Segtree{
int l,r;
ll a,b,sum;
}t[maxn<<4];
ll a[maxn], f[maxn];
inline void push_up(int rt){
t[rt].sum = (1ll * t[ls].sum + t[rs].sum) % mod;
}
void build(int rt,int l,int r){
t[rt].l = l, t[rt].r = r;
if(l == r) {
t[rt].sum = a[l];return ;
}
int mid = (l + r) >> 1;
build(ls,l,mid);build(rs,mid+1,r);
push_up(rt);
}
inline ll cal(ll a,ll b,int k){
if(k == 1) return a % mod;
if(k == 2) return b % mod;
return ((1ll * a * f[k-2]) % mod + (1ll * b * f[k-1]) % mod) % mod;
}
inline ll get_sum(ll a,ll b,int k){
if(k == 1) return a % mod;
if(k == 2) return (a + b) % mod;
return ((1ll * cal(a,b,k+2) - cal(a,b,2))%mod+mod)%mod;
}
inline void modify(int rt,ll a,ll b){
int k = t[rt].r - t[rt].l + 1;
t[rt].a = (1ll * t[rt].a + a) % mod, t[rt].b = (1ll * t[rt].b + b) % mod;
t[rt].sum = (1ll * t[rt].sum + get_sum(a,b,k)) % mod;
}
inline void push_down(int rt){
if(!t[rt].a) return ;
int l = t[rt].l ,r = t[rt].r ,mid = (l + r) >> 1;
ll a = t[rt].a, b = t[rt].b;
modify(ls,a,b);
ll aa = cal(a,b,mid-l+2), bb = cal(a,b,mid-l+3);
modify(rs,aa,bb);
t[rt].a = t[rt].b = 0;
}
void update(int rt,int L,int R,ll a,ll b){
int l = t[rt].l, r = t[rt].r;
if(L <= l && r <= R){
modify(rt,cal(a,b,l-L+1),cal(a,b,l-L+2));
return ;
}
push_down(rt);
int mid = (l + r) >> 1;
if(L <= mid) update(ls,L,R,a,b);
if(R > mid) update(rs,L,R,a,b);
push_up(rt);
}
ll query(int rt,int L,int R){
int l = t[rt].l, r = t[rt].r;
if(L <= l && r <= R){
return t[rt].sum % mod;
}
push_down(rt);
int mid = (l + r) >> 1;
ll res = 0;
if(L <= mid) res = (res + 1ll * query(ls,L,R)) % mod;
if(R > mid) res = (res + 1ll * query(rs,L,R)) % mod;
return res % mod;
}
void init(){
f[1] = f[2] = 1;
for(int i = 3;i < maxn;++i) f[i] = (1ll * f[i-2] + f[i-1]) % mod;
}
int main() {
init();
int n,m;scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
build(1,1,n);
while(m--){
int op,l,r;scanf("%d%d%d",&op,&l,&r);
if(op == 1) update(1,l,r,f[1],f[2]);
if(op == 2) printf("%lld\n", query(1,l,r) % mod);
}
return 0;
}