ZYH的斐波那契数列

Posted saionjisekai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZYH的斐波那契数列相关的知识,希望对你有一定的参考价值。

ZYH最近研究数列研究得入迷啦!

现在有一个斐波拉契数列(f[1]=f[2]=1,对于n>2有f[n]=f[n-1]+f[n-2]),

但是斐波拉契数列太简单啦,于是ZYH把它改成了斐波拉契的前缀和的数列{Si}(S[1]=1,对于n>1,有S[n]=S[n-1]+f[n]),接下来ZYH要在{Si}数列上面做一些操作。

1.修改: 将数列中下标在[l,r]区间内的数加上v

2.查询:询问此时数列第k项对1000000007取模后是多少。

你能帮他解决这两个操作吗?

对于 10%的数据有 n ≤10^3, l ≤ r ≤ 10^3 , k≤10^3 , v≤10^3

对于 30%的数据有 n ≤10^5 , l ≤ r ≤ 10^6 , k≤10^6 , v≤10^6

对于 60%的数据有 n ≤10^5 , l ≤ r ≤ 10^6 , k≤10^9 , v≤10^9

对于 100%的数据有 n ≤10^5 , l ≤ r ≤ 10^9 , k≤10^9 , v≤10^9

source:光华测试day1t3

 

矩阵快速幂就不说了,大家都会,这里粘一个板子参考

技术分享图片
 1 #include<cstdio>
 2 #include<cmath>//pow函数,其实没啥用 
 3 using namespace std;
 4 
 5 int n;long long k;
 6 const int N=pow(10,9)+7;
 7 struct node{long long  a[105][105];};
 8 node shu,ans,mp;
 9 //shu是输入的矩阵,ans是所求答案
10 node matrix(node x,node y){
11     for(int i=1;i<=n;i++)
12         for(int j=1;j<=n;j++){
13             mp.a[i][j]=0;
14             for(int p=1;p<=n;p++)
15                 mp.a[i][j]=(mp.a[i][j]+x.a[i][p] * y.a[p][j])%N;
16             //矩阵乘法 
17         }
18     return mp;
19 }
20 
21 int work(long long k){//矩阵快速幂 
22     while(k){
23         if(k&1) 
24             ans=matrix(ans,shu);
25         k>>=1;
26         shu=matrix(shu,shu);
27     }
28 }
29 
30 int main(){
31     scanf("%d%lld",&n,&k);
32     for(int i=1;i<=n;i++){ 
33         for(int j=1;j<=n;j++)
34             scanf("%d",&shu.a[i][j]);
35         ans.a[i][i]=1;//任何一个矩阵乘以单位矩阵,其值等于本身;
36     }       
37 
38     work(k);
39 
40     for(int i=1;i<=n;i++){
41         for(int j=1;j<=n;j++)
42             printf("%d ",ans.a[i][j]);
43         printf("
");
44     }
45     return 0;   
46 }
template

 

线段树几乎是板子

但是数据很大,显然不能硬来

看到询问很小于是离散化

排序之后请按13579进行映射,因为中间留的偶数是给那些在这些区间内被包含(不含两边)的数

那么离散化之后就很小了,直接线段树乱搞就行了

其实我没写std。。。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #define LL long long
  6 using namespace std;
  7 const int MAXN=1000001;
  8 const LL MOD=1e9+7;
  9 int n,m;
 10 LL tz;
 11 int tx,ty;
 12 struct NODE{
 13     int l,r;
 14     LL val;
 15     NODE()
 16     {
 17         l=r=0;val=0;
 18     }
 19 }tr[MAXN*4];
 20 int num=0;
 21 
 22 LL mod(LL x)
 23 {
 24     return x%MOD;
 25 }
 26 
 27 void Pushup(int x)
 28 {
 29     tr[x].val=mod(tr[tr[x].l].val+tr[tr[x].r].val);
 30 }
 31 
 32 void Update(int x,int L,int R,int aim,LL v)
 33 {
 34     if(L==R)
 35     {
 36         tr[x].val+=v;
 37         if(tr[x].val>=MOD)tr[x].val-=MOD;
 38         return ;
 39     }
 40     int mid=(L+R)/2;
 41     
 42     if(aim<=mid)
 43     {
 44         if(!tr[x].l)
 45         {
 46             tr[x].l=++num;
 47         }
 48         Update(tr[x].l,L,mid,aim,v);
 49     }
 50     else
 51     {
 52         if(!tr[x].r)
 53         {
 54             tr[x].r=++num;
 55         }
 56         Update(tr[x].r,mid+1,R,aim,v);
 57     }
 58     Pushup(x);
 59 }
 60 
 61 LL Query(int x,int L,int R,int al,int ar)
 62 {
 63     if(R<al||L>ar)return 0;
 64     if(al<=L&&R<=ar)
 65     {
 66         return tr[x].val;
 67     }
 68     int mid=(L+R)/2;
 69     return mod(Query(tr[x].l,L,mid,al,ar)+Query(tr[x].r,mid+1,R,al,ar));
 70 }
 71 
 72 struct Matrix{
 73     LL a[4][4];
 74     
 75     void QL()
 76     {
 77         for(int i=1;i<=3;i++)
 78             for(int j=1;j<=3;j++)
 79                 a[i][j]=0;
 80     }
 81     
 82     void DW()
 83     {
 84         QL();
 85         for(int i=1;i<=3;i++)a[i][i]=1ll;
 86     }
 87     
 88     void init()
 89     {
 90         QL();
 91         a[1][1]=1;a[1][2]=1;a[1][3]=1;
 92         a[2][1]=0;a[2][2]=1;a[2][3]=1;
 93         a[3][1]=0;a[3][2]=1;a[3][3]=0;
 94     }
 95 }p,l[1<<16],r[1<<16];
 96 
 97 Matrix mul(Matrix x,Matrix y)
 98 {
 99     Matrix z;
100     z.QL();
101     for(int i=1;i<=3;i++)
102     {
103         for(int j=1;j<=3;j++)
104         {
105             for(int k=1;k<=3;k++)
106             {
107                 z.a[i][j]=mod(z.a[i][j]+x.a[i][k]*y.a[k][j]);
108             }
109         }
110     }
111     return z;
112 }
113 
114 int main()
115 {
116     
117 //    freopen("george9.in","r",stdin);
118 //    freopen("george9.out","w",stdout);
119     
120     r[0].DW();
121     r[1].init();
122     for(int i=2;i<(1<<16);i++)
123     {
124         r[i]=mul(r[1],r[i-1]);
125     }
126     
127     l[0].DW();
128     l[1]=mul(r[(1<<16)-1],r[1]);
129     
130     for(int i=2;i<(1<<16);i++)
131     {
132         l[i]=mul(l[1],l[i-1]);
133     }
134     
135     scanf("%d",&n);
136     num++;
137     for(int i=1;i<=n;i++)
138     {
139         scanf("%d",&tx);
140         if(tx==1)
141         {
142             scanf("%d%d%lld",&tx,&ty,&tz);
143             Update(1,1,1000000001,tx,tz);
144             Update(1,1,1000000001,ty+1,-tz);
145         }
146         else
147         {
148             scanf("%d",&tx);
149             ty=tx-2;
150             LL ans=0;
151             if(tx<=2)ans=((LL)tx);
152             else
153             {
154                 p=mul(l[ty>>16],r[ty-((ty>>16)<<16)]);    
155                 ans=mod(2*p.a[1][1]+p.a[1][2]+p.a[1][3]);
156             }
157             
158             printf("%lld
",mod(mod(ans+Query(1,1,1000000001,1,tx))+MOD));
159         }
160     }
161     return 0;
162 }

 

以上是关于ZYH的斐波那契数列的主要内容,如果未能解决你的问题,请参考以下文章

使用reduce方法的斐波那契数列

使用数组和 For 循环的斐波那契数列

新的斐波那契数列

C++中的斐波那契数列不能超过47个数

P1-2017级算法第一次上机 A 水水的斐波那契数列

巨大的斐波那契数列