codeforces 446C 线段树 + fibnacci

来源:互联网 发布:javascript alert 1 编辑:程序博客网 时间:2024/06/06 02:19
C. DZY Loves Fibonacci Numbers
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 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.

题意,给定一个数列,区间更新,每次加上对应的fibnacci值。

思路,要用到两个定理:

假设正常的fibnacci值为fib[i](指以1 1为开头的数列),则以a,b开头的数列的第k个数为a * fib[k-2] + b * fib[k-1];

以a,b开头的k个数之和为fib[k+2] - fib[2](此处为b)

下面是代码:

#include <iostream>#include <algorithm>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <functional>#include <sstream>#include <iomanip>#include <cmath>#include <cstdlib>#include <ctime>//#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;#define INF 1e9#define MAXN 21#define maxn 300005#define mod 1000000009#define eps 1e-7#define pi 3.1415926535897932384626433#define rep(i,n) for(int i=0;i<n;i++)#define rep1(i,n) for(int i=1;i<=n;i++)#define scan(n) scanf("%d",&n)#define scanll(n) scanf("%I64d",&n)#define scan2(n,m) scanf("%d%d",&n,&m)#define scans(s) scanf("%s",s);#define ini(a) memset(a,0,sizeof(a))#define out(n) printf("%d\n",n)ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1ll add1[maxn<<2],add2[maxn<<2];ll fib[maxn];ll sum[maxn<<2];int n,m;void init(){fib[0] = 0;fib[1] = 1;for(int i = 2;i < maxn; i++) fib[i] = (fib[i-1] + fib[i-2]) % mod;}ll getFib(ll a,ll b,int k) //求以a,b开头的第k个数{if(k == 1) return a;if(k == 2) return b;return (a * fib[k-2] + b * fib[k-1]) % mod;}ll getFibsum(ll a,ll b,int k) //以a,b开头的k个数之和{if(k == 1) return a;if(k == 2) return a + b;return (getFib(a, b, k+2) - b + mod) % mod;}void PushUp(int rt) {sum[rt] = (sum[rt<<1] + sum[rt<<1|1]) % mod;}void build(int l,int r,int rt) {add1[rt] = 0;add2[rt] = 0;if (l == r) {scanf("%I64d",&sum[rt]);return ;}int m = (l + r) >> 1;build(lson);build(rson);PushUp(rt);}void add(ll a,ll b,int l,int r,int rt){sum[rt] = (sum[rt] + getFibsum(a,b,r-l+1)) % mod;add1[rt] = (add1[rt] + a) % mod;add2[rt] = (add2[rt] + b) % mod;}void PushDown(int l,int r,int rt) {if(add1[rt] || add2[rt]){int m = (l + r) >> 1;add(add1[rt],add2[rt],lson);add(getFib(add1[rt],add2[rt],m+1-l+1),getFib(add1[rt],add2[rt],m+2-l+1),rson);add1[rt] = add2[rt] = 0;}}void update(int L,int R,int l,int r,int rt) {if (L <= l && r <= R) {add(fib[l-L+1],fib[l-L+2],l,r,rt);return ;}PushDown(l , r , rt);int m = (l + r) >> 1;if (L <= m) update(L , R , lson);if (m < R) update(L , R, rson);PushUp(rt);}ll query(int L,int R,int l,int r,int rt) {if (L <= l && r <= R) {return sum[rt];}PushDown( l , r , rt);int m = (l + r) >> 1;ll ret = 0;if (L <= m) ret = (ret + query(L , R , lson)) % mod;if (m < R) ret = (ret + query(L , R , rson)) % mod;return ret;}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);#endif  init();while(~scanf("%d%d",&n,&m)){build(1,n,1);int ty,L,R;while(m--){//cout<<"aaa: "<<query(4,4,1,n,1)<<"bbb: "<<query(5,5,1,n,1)<<endl;scanf("%d%d%d",&ty,&L,&R);if(ty == 1) update(L,R,1,n,1);else{printf("%I64d\n",query(L,R,1,n,1));}}}return 0;}


0 0
原创粉丝点击