• codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新


    DZY Loves Fibonacci Numbers
    Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u
    Submit Status
    Appoint description: 

    Description

    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 arem queries, each query has one of the two types:

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

    Input
    4 4
    1 2 3 4
    1 1 4
    2 1 4
    1 2 4
    2 1 3
    Output
    17
    12

    Hint

    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.

    解题思路:根据斐波那契数列的两个定义(任意区间适应,a为该区间的第一项,b为该区间的第二项):

    (1)F(n)=b*fib[n-1]+a*fib[n-2] ;

    (2)F[1]+F[2]+...+F[n]=F[n+2]-b;

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 using namespace std;
      5 
      6 #define lson i<<1
      7 #define rson i<<1|1
      8 #define mid ((l+r)>>1)
      9 typedef __int64 LL;
     10 const int maxn=300005;
     11 const int mod=1e9+9;
     12 int a[maxn],fib[maxn];
     13 
     14 struct Node
     15 {
     16     int f1,f2;//区间第一项和第二项的值
     17     int sum;
     18 }segtree[maxn<<2];
     19 
     20 void init()//斐波那契数列预处理
     21 {
     22     fib[1]=1;fib[2]=1;
     23     for(int i=3;i<maxn;i++)
     24         if((fib[i]=fib[i-1]+fib[i-2])>=mod)
     25             fib[i]-=mod;
     26 }
     27 
     28 int get_fib(int a,int b,int n)
     29 {
     30     if(n==1) return a;
     31     if(n==2) return b;
     32     return ((LL)b*fib[n-1]+(LL)a*fib[n-2])%mod;
     33 }
     34 
     35 int get_sum(int a,int b,int n)
     36 {
     37     int sum=get_fib(a,b,n+2)-b;
     38     return (sum+mod)%mod;
     39 }
     40 void add_fib(int i,int l,int r,int a,int b)
     41 {
     42     segtree[i].f1=(segtree[i].f1+a)%mod;
     43     segtree[i].f2=(segtree[i].f2+b)%mod;
     44     segtree[i].sum=(segtree[i].sum+get_sum(a,b,r-l+1))%mod;
     45 }
     46 
     47 void pushdown(int i,int l,int r)
     48 {
     49     add_fib(lson,l,mid,segtree[i].f1,segtree[i].f2);
     50     add_fib(rson,mid+1,r,get_fib(segtree[i].f1,segtree[i].f2,mid+1-l+1)
     51         ,get_fib(segtree[i].f1,segtree[i].f2,mid-l+3));
     52     segtree[i].f1=segtree[i].f2=0;
     53 }
     54 
     55 void pushup(int i)
     56 {
     57     segtree[i].sum=(segtree[lson].sum+segtree[rson].sum)%mod;
     58 }
     59 
     60 void build(int i,int l,int r)
     61 {
     62     if(l==r)
     63     {
     64         segtree[i].sum=a[l];
     65         segtree[i].f1=segtree[i].f2=0;
     66         return ;
     67     }
     68     build(lson,l,mid);
     69     build(rson,mid+1,r);
     70     pushup(i);
     71 }
     72 
     73 void update(int i,int l,int r,int a,int b)
     74 {
     75     if(a<=l && r<=b)
     76     {
     77         add_fib(i,l,r,fib[l-a+1],fib[l-a+2]);
     78         return ;
     79     }
     80     pushdown(i,l,r);
     81     if(a<=mid) update(lson,l,mid,a,b);
     82     if(b>mid) update(rson,mid+1,r,a,b);
     83     pushup(i);
     84 }
     85 
     86 int query(int i,int l,int r,int a,int b)
     87 {
     88     if(a<=l && r<=b) 
     89         return segtree[i].sum;
     90     pushdown(i,l,r);
     91     int ans=0;
     92     if(a<=mid) ans=(ans+query(lson,l,mid,a,b))%mod;
     93     if(mid<b) ans=(ans+query(rson,mid+1,r,a,b))%mod;
     94     return ans;
     95 }
     96 
     97 int main()
     98 {
     99     init();
    100     int i,n,m,op,l,r;
    101     scanf("%d%d",&n,&m);
    102     for(i=1;i<=n;i++) scanf("%d",a+i);
    103     build(1,1,n);
    104     while(m--)
    105     {
    106         scanf("%d%d%d",&op,&l,&r);
    107         if(op==1) update(1,1,n,l,r);
    108         if(op==2) printf("%d
    ",query(1,1,n,l,r));
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    FineReport实现java报表报表展示的效果图
    Android开发最佳学习路线图
    void及void指针含义的深刻解析
    7个最好的免费杀毒软件下载
    linux-socket
    java实现第四届蓝桥杯逆波兰表达式
    java实现第四届蓝桥杯逆波兰表达式
    java实现第四届蓝桥杯逆波兰表达式
    java实现第四届蓝桥杯逆波兰表达式
    java实现第四届蓝桥杯有理数类
  • 原文地址:https://www.cnblogs.com/xiong-/p/3853223.html
Copyright © 2020-2023  润新知