码迷,mamicode.com
首页 > 其他好文 > 详细

斐波那契相关

时间:2020-06-29 22:49:59      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:技术   clu   处理   cas   const   ret   isp   tar   odi   

数论 斐波那契相关

1.1 斐波那契求和公式

\(f_n\)表示斐波那契数列的第\(n(n\not=1)\)项(\(f_0=1,f_1=1\)),则有下式:

\[f_n=\sum_{i=1}^{n-2}f_i+f_2 \]

证明

易证:\(f_2=f_2\)

\(n=i\)时成立,尝试证明\(n=i+1\)同样成立

技术图片

综上所述:结论成立

简单转化一下:

\[f_{n+2}=\sum_{i=1}^{n}f_i +f_2\Rightarrow \sum_{i=1}^{n}f_i=f_{n+2}-f_2 \]

\[\sum_{i=1}^{n}f_i=f_{n+2}-f_2 \]

2.1 广义斐波那契数列

斐波那契数列的特征:

技术图片

广义斐波那数列的特征

技术图片

2.2 广义斐波那契数列的求和公式

斐波那契求和公式

\[\sum_{i=1}^{n}=f_{n+2}-f_2 \]

回顾一下推导过程,其实只用到了\(f_n=f_{n-1}+f_{n-2}\)这一条性质,而在这一点上,广义斐波那契数列同样适用,因此求和公式可以类比:

\[\sum_{i=1}^nh_i=h_{n+2}-h_2 \]

2.3 广义斐波那契与斐波那契的转化关系

先摆出结论:

\[h_n=a\times f_{n-2} + b\times f_{n-1} \]

证明:

采用数学归纳法的思想:

\(n=2\)时,\(h_2=h_1\times 0 + h_2\times 1=a\times f_0+b\times f_1\),成立

\(n=3\)时,\(h_3=h_1+h_2=a\times f_1+b\times f_2\),成立

\(n=i-2,n=i-1\)均成立时,尝试证明\(n=i\)时也成立

技术图片

综上所述,结论成立

2.3 数列相加

结论: 任意两个广义斐波那契数列对应项相加,新的数列仍是个广义斐波那契数列

证明: 易证 (/ω\)

例题:CF446C DZY Loves Fibonacci Numbers

CF446C DZY Loves Fibonacci Numbers

题目大体一看,是线段树没跑了。但是,怎么下放标记?

由于题目的所有询问都只关心求和问题,那么使用求和公式即可。我们事先预处理出来\(1~n+2\)的斐波那契值(\(f_n\)),和递推式的前两项(\(a,b\)),就可以利用求和公式了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lor(a,b,c) for(register int a=b;a<=c;++a)
#define ror(a,b,c) for(register int a=c;a>=b;--a)

const int MAX=3e5+5;
const ll MOD=1e9+9;

int n,m;
ll fibo[MAX];
ll a[MAX],val[MAX<<2],lazy1[MAX<<2],lazy2[MAX<<2];

inline void init();
void build(int,int,int);
inline void pushdown(int,int,int);
inline void change(int,int,int,ll,ll);
inline ll calc(ll,ll,int);
inline ll qs(ll,ll,int);
ll query(int,int,int,int,int);
void modify(int,int,int,int,int);

int main(){
	#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	#endif

	scanf("%d%d",&n,&m); init();
	lor(i,1,n) scanf("%I64d",&a[i]);
	build(1,1,n);
	lor(i,1,m){
		int type,l,r; scanf("%d%d%d",&type,&l,&r);
		switch(type){
			case 1: modify(1,1,n,l,r); break;
			case 2: printf("%I64d\n",query(1,1,n,l,r)); break;
		}
	}

	return 0;
}

inline void init(){
	fibo[0]=0ll; fibo[1]=1ll;
	lor(i,2,n+2) fibo[i]=(fibo[i-1]+fibo[i-2])%MOD;
}

void build(int id,int l,int r){
	if(l==r) {val[id]=a[l]; return;}
	int mid=(l+r)>>1;
	build(id<<1,l,mid); build(id<<1|1,mid+1,r);
	val[id]=val[id<<1]+val[id<<1|1];
}

inline void pushdown(int id,int l,int r){
	if(!lazy1[id]&&!lazy2[id]) return;
	int mid=(l+r)>>1,len=mid-l+1;
	change(id<<1,l,mid,lazy1[id],lazy2[id]);
	change(id<<1|1,mid+1,r,qs(lazy1[id],lazy2[id],len+1),qs(lazy1[id],lazy2[id],len+2));
	lazy1[id]=lazy2[id]=0;
}

inline void change(int id,int l,int r,ll l1,ll l2){
	val[id]=(val[id]+calc(l1,l2,r-l+1))%MOD;
	lazy1[id]=(lazy1[id]+l1)%MOD;
	lazy2[id]=(lazy2[id]+l2)%MOD;
}

inline ll calc(ll a,ll b,int len){
	return (a*fibo[len]+b*(fibo[len+1]-1))%MOD;
}

inline ll qs(ll a,ll b,int k){
	if(k==1) return a;
	return (a*fibo[k-2]+b*fibo[k-1])%MOD;
}

ll query(int id,int l,int r,int L,int R){
	if(L<=l&&r<=R) return val[id];
	pushdown(id,l,r); int mid=(l+r)>>1; ll ans=0;
	if(L<=mid) ans=(ans+query(id<<1,l,mid,L,R))%MOD;
	if(mid+1<=R) ans=(ans+query(id<<1|1,mid+1,r,L,R))%MOD;
	return ans;
}

void modify(int id,int l,int r,int L,int R){
	if(L<=l&&r<=R) return change(id,l,r,fibo[l-L+1],fibo[l-L+2]);
	pushdown(id,l,r); int mid=(l+r)>>1;
	if(L<=mid) modify(id<<1,l,mid,L,R);
	if(mid+1<=R) modify(id<<1|1,mid+1,r,L,R);
	val[id]=(val[id<<1]+val[id<<1|1])%MOD;
}

斐波那契相关

标签:技术   clu   处理   cas   const   ret   isp   tar   odi   

原文地址:https://www.cnblogs.com/ticmis/p/13210692.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!