标签:技术 clu 处理 cas const ret isp tar odi
设\(f_n\)表示斐波那契数列的第\(n(n\not=1)\)项(\(f_0=1,f_1=1\)),则有下式:
证明:
易证:\(f_2=f_2\)
当\(n=i\)时成立,尝试证明\(n=i+1\)同样成立
综上所述:结论成立
简单转化一下:
斐波那契数列的特征:
广义斐波那数列的特征
斐波那契求和公式:
回顾一下推导过程,其实只用到了\(f_n=f_{n-1}+f_{n-2}\)这一条性质,而在这一点上,广义斐波那契数列同样适用,因此求和公式可以类比:
先摆出结论:
证明:
采用数学归纳法的思想:
当\(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\)时也成立
综上所述,结论成立
结论: 任意两个广义斐波那契数列对应项相加,新的数列仍是个广义斐波那契数列
证明: 易证 (/ω\)
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