博客讲的很好了,我自己写了250行,wa了十几次。。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<cctype>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<iomanip>
#include<sstream>
#include<cstdlib>
#include<ctime>
#include<list>
#include<deque>
#include<bitset>
#include<fstream>
#define ld double
#define ull unsigned long long
#define ll long long
#define pii pair<int,int >
#define iiii pair<int,pii >
#define mp make_pair
#define INF 1000000000
#define MOD 1000000007
#define rep(i,x) for(int (i)=0;(i)<(x);(i)++)
#define putchar IO::_putchar
#define getchar IO::_getchar
namespace IO
{
const int sz=1<<15;
char inbuf[sz],outbuf[sz];
char *pinbuf=inbuf+sz;
char *poutbuf=outbuf;
inline char _getchar()
{
if (pinbuf==inbuf+sz)fread(inbuf,1,sz,stdin),pinbuf=inbuf;
return *(pinbuf++);
}
inline void _putchar(char x)
{
if (poutbuf==outbuf+sz)fwrite(outbuf,1,sz,stdout),poutbuf=outbuf;
*(poutbuf++)=x;
}
inline void flush()
{
if (poutbuf!=outbuf)fwrite(outbuf,1,poutbuf-outbuf,stdout),poutbuf=outbuf;
}
}
inline int getint()
{
int x=0,p=1;char c=getchar();
while (c<=32)c=getchar();
if(c==45)p=-p,c=getchar();
while (c>32)x=x*10+c-48,c=getchar();
return x*p;
}
void put_int(int x)
{
if(x==0)return;
put_int(x/10);putchar(x%10+48);
}
void putint(int x)
{
if(x==0)putchar(48);
else
{
if(x<0)putchar(45),x=-x;
put_int(x);
}
putchar('\n');
}
//
const int maxn=2e5+5;
const int mod=1e9;
inline int add(int x,int y)
{
return x+y>mod?x+y-mod:x+y;
}
inline int mul(int x,int y)
{
return (1ll*x*y)%mod;
}
struct M
{
int d[2][2];
M(int x=0)
{
rep(i,2)rep(j,2)d[i][j]=1ll*(i==j)*x;
}
M operator *(const M &b)const
{
M ans;
rep(i,2)rep(j,2)rep(k,2)
ans.d[i][j]=add(ans.d[i][j],mul(d[i][k],b.d[k][j]));
return ans;
}
M operator +(const M &b)const
{
M ans;
rep(i,2)rep(j,2)ans.d[i][j]=add(d[i][j],b.d[i][j]);
return ans;
}
};
M mm[maxn];
bool ok[maxn];
inline M modpow(int y)
{
if(ok[y])return mm[y];
ok[y]=true;
M ans(1);
ans=modpow(y>>1)*modpow(y>>1);
if(y&1)ans=ans*mm[1];
return mm[y]=ans;
}
int a[maxn],n,t,fib[maxn],pre[maxn];
struct node
{
M s;
int len;
node(){len=0;}
node(M _s,int _len){s=_s,len=_len;}
node operator +(const node &b)const
{
if(len<=0)return b;
if(b.len<=0)return *this;
return node(s+b.s*modpow(len),len+b.len);
}
void operator +=(ll b)
{
s.d[0][0]=add(s.d[0][0],mul(pre[len-1],b));
s.d[0][1]=add(s.d[0][1],mul(pre[len]-1,b));
}
int v(){return s.d[0][0];}
};
namespace T
{
int m=1;
ll lazy[maxn<<2]={0};
node dat[maxn<<2];
void build(int k,int l,int r)
{
if(r-l<=1)
{
dat[k].len=1;
dat[k].s.d[0][0]=dat[k].s.d[0][1]=a[l];
return;
}
build(2*k+1,l,(l+r)>>1);
build(2*k+2,(l+r)>>1,r);
dat[k]=dat[2*k+1]+dat[2*k+2];
}
void pushdown(int k,int l,int r)
{
if(lazy[k]==0||r-l==1)return;
lazy[2*k+1]=add(lazy[2*k+1],lazy[k]);
lazy[2*k+2]=add(lazy[2*k+2],lazy[k]);
dat[2*k+1]+=lazy[k];
dat[2*k+2]+=lazy[k];
lazy[k]=0;
}
node query(int x,int y,int l,int r,int k)
{
pushdown(k,l,r);
if(l>=y||r<=x)return node(M(0),0);
else if(x<=l&&r<=y)return dat[k];
else
{
node lx=query(x,y,l,(l+r)>>1,2*k+1);
node ly=query(x,y,(l+r)>>1,r,2*k+2);
return lx+ly;
}
}
void modify(int x,int y,int l,int r,int k,ll del)
{
pushdown(k,l,r);
if(l>=y||r<=x)return;
else if(x<=l&&r<=y)
{
lazy[k]+=del;
dat[k]+=del;
pushdown(k,l,r);
}
else
{
modify(x,y,l,(l+r)>>1,2*k+1,del);
modify(x,y,(l+r)>>1,r,2*k+2,del);
dat[k]=dat[2*k+1]+dat[2*k+2];
}
}
void fM(int x,int l,int r,int k,ll del)
{
pushdown(k,l,r);
if(r-l==1)dat[k].s.d[0][0]=dat[k].s.d[0][1]=del;
else
{
int mid=(l+r)>>1;
if(x<mid)fM(x,l,mid,2*k+1,del);
else fM(x,mid,r,2*k+2,del);
dat[k]=dat[2*k+1]+dat[2*k+2];
}
}
}
void finit()
{
ok[0]=true;
mm[0].d[0][0]=mm[0].d[1][1]=1;
ok[1]=true;
mm[1].d[0][1]=mm[1].d[1][0]=mm[1].d[1][1]=1;
fib[0]=fib[1]=pre[0]=1;pre[1]=2;
for(int i=2;i<maxn;i++)
{
fib[i]=add(fib[i-1],fib[i-2]);
pre[i]=add(pre[i-1],fib[i]);
}
n=getint();t=getint();
rep(i,n)a[i]=getint();
T::build(0,0,n);
}
void solve()
{
rep(i,t)
{
int op=getint(),x=getint()-1,y=getint();
if(op==1)T::fM(x,0,n,0,y);
else if(op==2)putint(T::query(x,y,0,n,0).v());
else
{
ll del=getint();
T::modify(x,y,0,n,0,del);
}
}
IO::flush();
}
int main()
{
finit();
solve();
return 0;
}