思路
斐波那契数的一个性质:,题目中对区间操作时,位于的元素加了,根据上述公式拆一下得到,发现和与无关,因此只维护下和的标记就可以了。
另外,斐波那契数列的通项公式:
代码
#include<bits/stdc++.h>
#define lc p<<1
#define rc p<<1|1
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define en puts("")
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll>
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
void read() {}
void OP() {}
void op() {}
template <typename T, typename... T2>
inline void read(T &_, T2 &... oth)
{
int __=0;
_=0;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
__=1;
ch=getchar();
}
while(isdigit(ch))
{
_=_*10+ch-48;
ch=getchar();
}
_=__?-_:_;
read(oth...);
}
template <typename T>
void Out(T _)
{
if(_<0)
{
putchar('-');
_=-_;
}
if(_>=10)
Out(_/10);
putchar(_%10+'0');
}
template <typename T, typename... T2>
inline void OP(T _, T2... oth)
{
Out(_);
putchar('\n');
OP(oth...);
}
template <typename T, typename... T2>
inline void op(T _, T2... oth)
{
Out(_);
putchar(' ');
op(oth...);
}
/*#################################*/
const ll N=3E5+19,P=1E9+9;
ll n,m;
ll a[N],f[N],sf[N],neg[N],t[4*N],tag1[4*N],tag2[4*N];
void update(ll p)
{
t[p]=(t[lc]+t[rc])%P;
}
void build(ll p,ll l,ll r)
{
if(l==r)
{
t[p]=a[l];
return;
}
ll mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
update(p);
}
void flag(ll p,ll l,ll r,ll x,ll y)
{
t[p]=(t[p]+(sf[r+1]-sf[l]+P)%P*x%P)%P;
t[p]=(t[p]+(sf[r]-sf[l-1]+P)%P*y%P)%P;
tag1[p]=(tag1[p]+x)%P;
tag2[p]=(tag2[p]+y)%P;
}
void push_down(ll p,ll l,ll r)
{
ll mid=(l+r)>>1;
flag(lc,l,mid,tag1[p],tag2[p]);
flag(rc,mid+1,r,tag1[p],tag2[p]);
tag1[p]=tag2[p]=0;
}
void modify(ll p,ll l,ll r,ll al,ll ar)
{
if(al<=l && ar>=r)
{
flag(p,l,r,neg[al-1],neg[al]);
return;
}
if(tag1[p] || tag2[p])
push_down(p,l,r);
ll mid=(l+r)>>1;
if(al<=mid)
modify(lc,l,mid,al,ar);
if(ar>mid)
modify(rc,mid+1,r,al,ar);
update(p);
}
ll query(ll p,ll l,ll r,ll al,ll ar)
{
if(al<=l && ar>=r)
return t[p];
if(tag1[p] || tag2[p])
push_down(p,l,r);
ll mid=(l+r)>>1,ret=0;
if(al<=mid)
ret=(ret+query(lc,l,mid,al,ar))%P;
if(ar>mid)
ret=(ret+query(rc,mid+1,r,al,ar))%P;
return ret;
}
void print()
{
rep(i,1,4*n)
OP(t[i]);
en;
}
int main()
{
read(n,m);
rep(i,1,n)
read(a[i]);
f[1]=f[2]=1;
neg[1]=1;
rep(i,3,n+1)
f[i]=(f[i-1]+f[i-2])%P;
rep(i,2,n)
neg[i]=i&1?f[i]:P-f[i];
rep(i,1,n+1)
sf[i]=(sf[i-1]+f[i])%P;
build(1,1,n);
ll ty,l,r;
while(m--)
{
read(ty,l,r);
if(ty==1)
modify(1,1,n,l,r);
else
OP(query(1,1,n,l,r));
}
}