这道题和线段树1都是区间加,这道题不处理边界过不了?

P3368 【模板】树状数组 2

这里没判 mid,不知道线段树那题您有没有判?
by 朦胧_XY @ 2023-11-01 17:14:32


判 mid 了应该就不用判边界。@[RingTouSou](/user/1034242)
by 朦胧_XY @ 2023-11-01 17:17:45


```cpp #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 100005 #define LL long long #define lc u<<1 //除二 #define rc u<<1|1 //除二+1 LL w[N]; struct Tree { LL l,r,sum,add; //线段树 }tr[N*4]; void pushup(LL u){ //上传 (父节点) tr[u].sum=tr[lc].sum+tr[rc].sum; } void pushdown(LL u) //往下传 (父节点) { if(tr[u].add) { tr[lc].sum+=tr[u].add*(tr[lc].r-tr[lc].l+1); tr[rc].sum+=tr[u].add*(tr[rc].r-tr[rc].l+1); tr[lc].add+=tr[u].add; tr[rc].add+=tr[u].add; tr[u].add=0; } } void build(LL u,LL l,LL r) //建树 (父节点,左端点,右端点) { tr[u]={l,r,w[l],0}; if(l==r) return; LL m=l+r>>1; //除二 build(lc,l,m); build(rc,m+1,r); pushup(u); } void change(LL u,LL l,LL r,LL k) //区间修(父节点,总左端点,总右端点,每段加多少) { if(l>tr[u].r || r<tr[u].l) return; if(l<=tr[u].l&&tr[u].r<=r) { tr[u].sum+=(tr[u].r-tr[u].l+1)*k; tr[u].add+=k; //先用懒标记存起来 return; //如果被全包含,直接返回 } LL m=tr[u].l+tr[u].r>>1; //除二 pushdown(u); if(l<=m) change(lc,l,r,k); if(r>m) change(rc,l,r,k); pushup(u); } LL query(LL u,LL l,LL r){ //区间查找(输出) (父节点,总左端点,总右端点) if(l<=tr[u].l&&tr[u].r<=r) return tr[u].sum; LL m=tr[u].l+tr[u].r>>1; //除二 pushdown(u); LL sum=0; if(l<=m) sum+=query(lc,l,r); if(r>m) sum+=query(rc,l,r); return sum; } int main() { int n,m,op,x,y,k; cin>>n>>m; for(int i=1;i<=n;++i) cin>>w[i]; build(1,1,n); while(m--) { cin>>op>>x>>y; if(op==2) cout<<query(1,x,y)<<endl; else cin>>k,change(1,x,y,k); } return 0; } ``` @[朦胧_XY](/user/358971) 这是那道题的
by RingTouSou @ 2023-11-01 17:27:38


@[朦胧_XY](/user/358971) 刚好在学这个,请问mid什么意思
by RingTouSou @ 2023-11-01 17:30:07


你要是写 ```cpp if(l<=m) change(lc,l,r,k); if(r>m) change(rc,l,r,k); ``` 这种就不需要判
by jijidawang @ 2023-11-01 17:34:22


@[RingTouSou](/user/1034242) 就是特判 `if(l<=m)` 和 `if(r>m)` 。
by 朦胧_XY @ 2023-11-01 17:35:05


@[朦胧_XY](/user/358971) 谢谢,关注了
by RingTouSou @ 2023-11-01 20:44:11


|