# 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;
}