CF 316E3(Summer Homework-广意Fib数列在p,q=1时的性质-Fib线段树)

E3. Summer Homework
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

By the age of three Smart Beaver mastered all arithmetic operations and got this summer homework from the amazed teacher:

You are given a sequence of integers a1, a2, ..., an. Your task is to perform on it m consecutive operations of the following type:

  1. For given numbers xi and vi assign value vi to element axi.
  2. For given numbers li and ri you've got to calculate sum , where f0 = f1 = 1 and at i ≥ 2fi = fi - 1 + fi - 2.
  3. For a group of three numbers li ri di you should increase value ax by di for all x (li ≤ x ≤ ri).

Smart Beaver planned a tour around great Canadian lakes, so he asked you to help him solve the given problem.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 2·105) — the number of integers in the sequence and the number of operations, correspondingly. The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 105). Then follow m lines, each describes an operation. Each line starts with an integer ti (1 ≤ ti ≤ 3) — the operation type:

  • if ti = 1, then next follow two integers xi vi (1 ≤ xi ≤ n, 0 ≤ vi ≤ 105);
  • if ti = 2, then next follow two integers li ri (1 ≤ li ≤ ri ≤ n);
  • if ti = 3, then next follow three integers li ri di (1 ≤ li ≤ ri ≤ n, 0 ≤ di ≤ 105).

The input limits for scoring 30 points are (subproblem E1):

  • It is guaranteed that n does not exceed 100m does not exceed 10000 and there will be no queries of the 3-rd type.

The input limits for scoring 70 points are (subproblems E1+E2):

  • It is guaranteed that there will be queries of the 1-st and 2-nd type only.

The input limits for scoring 100 points are (subproblems E1+E2+E3):

  • No extra limitations.

Output

For each query print the calculated sum modulo 1000000000 (109).

Sample test(s)
input
5 5
1 3 1 2 4
2 1 4
2 1 5
2 2 4
1 3 10
2 1 5
output
12
32
8
50
input
5 4
1 3 1 2 4
3 1 4 1
2 2 4
1 2 10
2 1 5
output
12
45


艰难滴完成了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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值