区间阶梯和及单点更新

# include <bits/stdc++.h>
# define lson l, mid, id<<1
# define rson mid+1, r, id<<1|1
using namespace std;
typedef long long LL;
const int maxn = 1e5+30;
LL a[maxn], s[maxn], b[maxn<<2];
LL sum[maxn<<2],lazy[maxn<<2];
void build(int l, int r, int id){
    if(l == r){
        sum[id] = s[l];
        return;
    }
    int mid = l+r>>1;
    build(lson);
    build(rson);
    sum[id] = sum[id<<1]+sum[id<<1|1];
}
void pushdown(int id, int l, int r){
    if(lazy[id]){
        lazy[id<<1] += lazy[id];
        lazy[id<<1|1] += lazy[id];
        int mid = l+r>>1;
        sum[id<<1] += lazy[id]*(mid-l+1);
        sum[id<<1|1] += lazy[id]*(r-mid);
        lazy[id] = 0;
    }
}
void update(int L, int R, LL num, int l, int r, int id){
    if(L<=l && R>=r){
        sum[id] += (r-l+1)*num;
        lazy[id] += num;
        return;
    }
    int mid = l+r>>1;
    pushdown(id, l, r);
    if(L<=mid) update(L, R, num, lson);
    if(R>mid) update(L, R, num, rson);
    sum[id] = sum[id<<1]+sum[id<<1|1];
}
LL dan(int pos, int l, int r, int id){
    if(l == r){
        return sum[id];
    }
区间阶梯和及单点更新
Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]
Unfortunately, the longer he learns, the fewer he gets.
That means, if he reads books from l to r, he wil get 

a[l] x L + a[l+1] x (L-1) + … + a[r-1] x 2 + a[r]a[l] × L+a[l+1] × (L−1)+⋯+a[r−1]×2+a[r] 
(L is the length of [ l, r ] that equals to r - l + 1).

Now Ryuji has qq questions, you should answer him:
1. If the question type is 1, you should answer how much knowledge he wil get after he reads books [ l, r ].
2. If the question type is 2, Ryuji wil change the ith book's knowledge to a new value.
样例输入 
5 3
1 2 3 4 5
1 1 3
2 5 0
1 4 5
样例输出 
10
8
个人思想:
AI存原组,开CI维护AI的区间和
BI存对应阶段值,开DI维护BI区间和
操作2就修改AI及CI,BI及DI
操作1用DI,CI求区间阶梯和与区间和
例如求[1,3]区间的阶梯和值
ans=(b1+b2+b3)-(a1+a2+a3)*2
答案=梯阶和-区间区*(右区间值-1)



pushdown(id, l, r);
    int mid = l+r>>1;
    LL res;
    if(pos <= mid) res = dan(pos,lson);
    else res = dan(pos, rson);
    sum[id] = sum[id<<1]+sum[id<<1|1];
    return res;
}
LL query(int L, int R, int l, int r, int id){
    if(L<=l && R>=r){
        return sum[id];
    }
    pushdown(id, l, r);
    LL res = 0;
    int mid = l+r>>1;
    if(L<=mid) res += query(L, R, lson);
    if(R>mid) res += query(L, R, rson);
    sum[id] = sum[id<<1]+sum[id<<1|1];
    return res;
}
int main(){
    int  op, l, r, n, q;
    scanf("%d%d",&n,&q);
    LL tmp = 0;
    for(int i=1; i<=n; ++i){
        scanf("%lld",&a[i]);
        s[i] = s[i-1]+a[i];
    }
    build(1, n, 1);
    while(q--){
        scanf("%d%d%d",&op,&l,&r);
        if(op == 1){
            LL tmp = query(l ,r, 1, n, 1);
            LL tmp2 = 0;
            if(l-1 > 0 ) tmp2 = dan(l-1, 1, n, 1);
            printf("%lld\n",tmp-tmp2*(r-l+1));
        }
        else{
            update(l, n, 1LL*r-a[l], 1, n, 1);
            a[l] = 1LL*r;
        }
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值