sdutB - 这题就是线段树

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N=1e5+55;

const int INF=1e9+7;

struct date

{

    LL l,r,sum,sums,add;

}arr[4*N];

LL m,n,arr1[N];

void pushup(struct date &root,struct date &left,struct date &right)

{

    root.sum=(left.sum+right.sum)%INF;

    root.sums=(left.sums+right.sums)%INF;

}

void pushup(LL u)

{

    pushup(arr[u],arr[u<<1],arr[u<<1|1]);

}

void pushdown(LL u)

{

    if(arr[u].add!=0)

    {

        LL num=arr[u].add;

        arr[u<<1].add=arr[u<<1].add%INF+num%INF;

        arr[u<<1|1].add=arr[u<<1|1].add%INF+num%INF;

        arr[u<<1].sums=(arr[u<<1].sums%INF+(arr[u<<1].r-arr[u<<1].l+1)*num%INF*num%INF+2*num*arr[u<<1].sum%INF)%INF;

        arr[u<<1].sum=(arr[u<<1].sum%INF+(arr[u<<1].r-arr[u<<1].l+1)*num%INF)%INF;

        arr[u<<1|1].sums=(arr[u<<1|1].sums%INF+(arr[u<<1|1].r-arr[u<<1|1].l+1)*num%INF*num%INF+2*num*arr[u<<1|1].sum%INF)%INF;

        arr[u<<1|1].sum=(arr[u<<1|1].sum%INF+(arr[u<<1|1].r-arr[u<<1|1].l+1)*num%INF)%INF;

        arr[u].add=0;

    }

}

void build(LL u,LL l,LL r)

{

    arr[u].l=l,arr[u].r=r;

    if(l==r)

    {

        arr[u].sum=arr1[l]%INF;

        arr[u].sums=arr1[l]*arr1[l]%INF;

        arr[u].add=0;

        return;

    }

    LL mid=l+r>>1;

    build(u<<1,l,mid);

    build(u<<1|1,mid+1,r);

    pushup(u);

}

LL  query(LL u,LL l,LL r)

{

    if(arr[u].l>=l&&arr[u].r<=r)

    {

        return arr[u].sums%INF;

    }

    pushdown(u);

    LL mid=arr[u].l+arr[u].r>>1;

    LL sum=0;

    if(mid>=l) sum+=query(u<<1,l,r)%INF;

    if(mid<r) sum+=query(u<<1|1,l,r)%INF;

    return sum%INF;

}

void modify(LL u,LL l,LL r,LL c)

{

    if(arr[u].l>=l&&arr[u].r<=r)

    {

        arr[u].add+=c;

        arr[u].add%=INF;

        arr[u].sums=(arr[u].sums%INF+(arr[u].r-arr[u].l+1)*c%INF*c%INF+2*c*arr[u].sum%INF)%INF;

        arr[u].sum=(arr[u].sum%INF+(arr[u].r-arr[u].l+1)*c%INF)%INF;

        return;

    }

    pushdown(u);

    LL mid=arr[u].l+arr[u].r>>1;

    if(mid>=l) modify(u<<1,l,r,c);

    if(mid<r) modify(u<<1|1,l,r,c);

    pushup(u);

}

int main()

{

    cin>>n;

    for(int i=1;i<=n;i++)

    {

        cin>>arr1[i];

    }

    build(1,1,n);

    cin>>m;

    while(m--)

    {

        int w;

        cin>>w;

        if(w==1)

        {

            LL w1,w2;

            cin>>w1>>w2;

            cout<<query(1,w1,w2)<<'\n';

        }

        else if(w==0)

        {

            LL w1,w2,w3;

            cin>>w1>>w2>>w3;

            modify(1,w1,w2,w3);

        }

    }

    return 0;

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值