covonant @ 2024-11-15 15:13:44
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
typedef long long LL;
LL lzy[4*maxn],a[maxn],w[4*maxn];
int n;
void pushup(int u){
w[u]=w[u*2]+w[u*2+1];
}
void build(int u,int L,int R){
if(L==R){
w[u]=a[L];
return;
}
int M=(L+R)/2;
build(u*2,L,M);build(u*2+1,M+1,R);
pushup(u);
}
void maketag(int u,int len,int x){
lzy[u]+=x;
w[u]+=len*x;
}
void pushdown(int u,int L,int R){
int M=(L+R)/2;
maketag(u*2,M-L+1,lzy[u]);
maketag(u*2+1,R-M,lzy[u]);
lzy[u]=0;
}
bool InRange(int L,int R,int l,int r){
return (l<=L)&&(R<=r);
}
bool OutofRange(int L,int R,int l,int r){
return (L>r)||(R<l);
}
LL query(int u,int L,int R,int l,int r){
if(InRange(L,R,l,r)){
return w[u];
}else if(!OutofRange(L,R,l,r)){
int M=(L+R)/2;
pushdown(u,L,R);
return query(u*2,L,M,l,r)+query(u*2+1,M+1,R,l,r);
}
}
void update(int u,int L,int R,int l,int r,LL x){
if(InRange(L,R,l,r)){
maketag(u,R-L+1,x);
}else if(!OutofRange(L,R,l,r)){
int M=(L+R)/2;
pushdown(u,L,R);
update(u*2,L,M,l,r,x);
update(u*2+1,M+1,R,l,r,x);
pushup(u);
}
}
int main(){
// freopen("P3372_1.in","r",stdin);
// freopen("data.in","w",stdout);
ios::sync_with_stdio(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
int op,x,y;
LL k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
update(1,1,n,x,y,k);
}else{
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
}
return 0;
}
by adsd45666 @ 2024-11-15 15:25:50
个人觉得应该是query和update的边界问题,在向下递归处理时,不能直接处理。
不是
return query(l,r,ls(p),pl,mid)+query(l,r,rs(p),mid+1,r);
而是
int x;
if(l<=mid) x+=query(l,r,ls(p),pl,mid);
if(r>mid) x+=query(l,r,rs(p),mid+1,pr);
return x;
否则就会遍历到不存在的区间,导致RE
by adsd45666 @ 2024-11-15 15:26:43
对了,x记得赋初值为0
by covonant @ 2024-11-15 23:47:18
@adsd45666 谢谢大佬已过Orz