艰难滴完成了E题……感觉不会再爱了
好吧,题目那个解法由于智商太低没看懂……
说一下我最后乱推的结果
设S(0)=F1a1+F2a2+..+Fnan
+)S(1)=F2a2+F3a3+..+F3a3
= (F1+F2)a2+(F2+F3)a3+..+(Fn-1+Fn)an
= F3 a3+ F4 a3+..+ Fn+1 an
于是我XXXXX……
只要存S0和S1就行了 Sx可以用关于S0和S1的表达式表示:Sx=Fn-2*S0 +Fn-1*S1 (系数为什么是Fib数?因为Sx=Sx-1+Sx-2的不明公式,可用数学归纳法证)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MAXN (200000+10)
#define F (1000000000)
#define Lson (x<<1)
#define Rson ((x<<1)+1)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
//void inv(long long a,long long b){return exgcd(a,}
int n,m;
long long f[MAXN],sf[MAXN]={0},f2[MAXN],sf2[MAXN];
struct arr_t
{
long long a[MAXN*4],s0[MAXN*4],s1[MAXN*4],b[MAXN*4];
arr_t(){MEM(a)MEM(s0)MEM(s1)MEM(b)}
long long S(int x,int n) //求的是S(x)
{
if (n==1) return s0[x];
if (n==2) return s1[x];
return add(mul(f[n-2],s0[x]),mul(f[n-1],s1[x]));
}
void update(int x,int l,int r)
{
int n=r-l+1,m=(l+r)>>1,ls=m-l+1,rs=n-ls;
s0[x]=(s0[Lson]+S(Rson,ls+1))%F;
s1[x]=(s1[Lson]+S(Rson,ls+2))%F;
}
void change(int x,int n,int c)
{
s0[x]=add(s0[x],mul(sf[n],c));
s1[x]=add(s1[x],mul(sf2[n],c));
}
void pushdown(int x,int l,int r)
{
if (l==r) return;
else if (b[x])
{
int n=r-l+1,m=(l+r)>>1,ls=m-l+1,rs=n-ls;
s0[Lson]=add(s0[Lson],mul(sf[ls],b[x]));
s0[Rson]=add(s0[Rson],mul(sf[rs],b[x]));
s1[Lson]=add(s1[Lson],mul(sf2[ls],b[x]));
s1[Rson]=add(s1[Rson],mul(sf2[rs],b[x]));
b[Lson]+=b[x];b[Rson]+=b[x];b[x]=0;
}
}
void ins(int x,int l,int r,int L,int R,int c)
{
pushdown(x,l,r);
int n=r-l+1,m=(l+r)>>1;
if (L<=l&&r<=R) {b[x]+=c;change(x,n,c);return;}
if (L<=m) ins(Lson,l,m,L,R,c);
if (m<R) ins(Rson,m+1,r,L,R,c);
update(x,l,r);
}
void modify(int x,int l,int r,int L,int c)
{
pushdown(x,l,r);
int n=r-l+1,m=(l+r)>>1;
if (l==r) {s0[x]=s1[x]=c;return;}
if (L<=m) modify(Lson,l,m,L,c);
else modify(Rson,m+1,r,L,c);
update(x,l,r);
}
void build(int x,int l,int r)
{
if (l==r) {scanf("%d",&a[x]);s0[x]=s1[x]=a[x]; return ;}
int n=r-l+1,m=(l+r)>>1;
build(Lson,l,m);
build(Rson,m+1,r);
update(x,l,r);
}
long long qur(int x,int l,int r,int L,int R)
{
pushdown(x,l,r);
int n=r-l+1,m=(l+r)>>1;
if (L<=l&&r<=R) {return S(x,l-(L-1));}
long long ans=0;
if (L<=m) ans=add(ans,qur(Lson,l,m,L,R));
if (m<R) ans=add(ans,qur(Rson,m+1,r,L,R));
return ans;
}
}T;
int main()
{
//freopen("homework.in","r",stdin);
//freopen(".out","w",stdout);
scanf("%d%d",&n,&m);
f[1]=f[2]=sf[1]=1,sf[2]=2;Fork(i,3,n) f[i]=(f[i-1]+f[i-2])%F,sf[i]=(sf[i-1]+f[i])%F;
f2[1]=sf2[1]=1,f2[2]=2;sf2[2]=3;Fork(i,3,n) f2[i]=(f2[i-1]+f2[i-2])%F,sf2[i]=(sf2[i-1]+f2[i])%F;
T.build(1,1,n);
For(i,m)
{
int p,x,v,l,r,d;scanf("%d",&p);
if (p==1)
{
scanf("%d%d",&x,&v);T.modify(1,1,n,x,v);
}
else if (p==2)
{
scanf("%d%d",&l,&r);cout<<T.qur(1,1,n,l,r)<<endl;
}
else
{
scanf("%d%d%d",&l,&r,&d);T.ins(1,1,n,l,r,d);
}
}
return 0;
}