huyangmu @ 2023-12-11 22:55:01
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int NR = 1e5 + 5;
int n,m,id,x,y,k,a[NR],tree[4 * NR],tag[4 * NR];
void pushup (int x){
tree[x] = tree[(x << 1)] + tree[(x << 1) + 1];
return ;
}
void addtag (int l,int r,int x,int val){
tag[x] += val;
tree[x] += (r - l + 1) * val;
return ;
}
void pushdown (int l,int r,int x){
if (tag[x] == 0) return ;
int mid = l + r >> 1;
addtag(l,mid,(x << 1),tag[(x << 1)]);
addtag(mid + 1,r,(x << 1) + 1,tag[(x << 1) + 1]);
tag[x] = 0;
return ;
}
void build (int l,int r,int x){
if (l == r){
tree[x] = a[l];
return ;
}
int mid = l + r >> 1;
build(l,mid,(x << 1));
build(mid + 1,r,(x << 1) + 1);
pushup(x);
return ;
}
int query (int l,int r,int x,int y,int cur){
if (y < l || x > r) return 0;
if (x <= l && r <= y) return tree[cur];
pushdown(l,r,cur);
int mid = l + r >> 1;
return query(l,mid,x,y,(cur << 1)) + query(mid + 1,r,x,y,(cur << 1) + 1);
}
void update (int l,int r,int x,int y,int cur,int val){
if (y < l || x > r) return ;
if (l == r && x <= l && r <= y){
addtag(l,r,cur,val);
return ;
}
pushdown(l,r,cur);
int mid = l + r >> 1;
update(l,mid,x,y,(cur << 1),val);
update(mid + 1,r,x,y,(cur << 1) + 1,val);
pushup(cur);
return ;
}
signed main (){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for (int i = 1;i <= n; ++i) cin >> a[i];
build (1,n,1);
while (m--){
cin >> id;
if (id == 1){
cin >> x >> y >> k;
update(1,n,x,y,1,k);
}else{
cin >> x >> y;
cout << query (1,n,x,y,1) << '\n';
}
}
return 0;
}
by HYdroKomide @ 2023-12-11 22:57:33
@HuYangMu2011 pushdown 那里 add 的 tag 写错了。
by huyangmu @ 2023-12-11 22:58:44
具体是哪@HYdroKomide
by HYdroKomide @ 2023-12-11 23:00:01
@HuYangMu2011 pushdown 那里的 addtag 函数里,应该都传 tag[x],你看看你传的是什么
by huyangmu @ 2023-12-11 23:02:47
%%% 关注了@HYdroKomide
by hsdqiu @ 2023-12-16 19:38:31
我猜是query的递归返回条件不对 你这个和我的写法不一样,但是我的是多加了第一个else if,然后就不超时了。 原本的是每次都到根节点才返回
int query(int k, int l, int r) //当前到了编号为k的节点,查询[l..r]的和
{
if (a[k].l == a[k].r)
return a[k].sum;
else if (a[k].l == l && a[k].r == r)
return a[k].sum;
//else,要往下查询子节点,而lazy标记的影响还未必下传给了子节点,所以要下传lazy标记
if (a[k].add)
pushdown(k);
int mid = (a[k].l + a[k].r) / 2;
if (r <= mid)
return query(k * 2, l, r);
else if (l > mid)
return query(k * 2 + 1, l, r);
else
return query(k * 2, l, mid) + query(k * 2 + 1, mid + 1, r);
}