这道题线段树写法求助

P3374 【模板】树状数组 1

``` void update(int o,int L,int R){ if(L==R){ sum[o]=a[y]=z; return ; } int m=(L+R)/2; if(y<=m) update(o*2,L,m); if(z>m) update(o*2+1,m+1,R);//这里改成else sum[o]=sum[o*2]+sum[o*2+1]; } ```
by __uint256_t @ 2022-02-11 09:33:44


@[段鉴泽](/user/251779) 单点修改,把 `update` 里面的 `if(z>m)` 改成 `else`
by aqx_AK_xyf @ 2022-02-11 09:36:18


@[段鉴泽](/user/251779) 帮您调过了 1. 题目中 $n\le 5\times 10^5$,所以 $a$ 要开到 $5e5$,$sum$ 要开到 $2e6$。 2. 题目中的修改是 `+=`,不是 `=`。 3. 若修改或查询的范围与区间 $[L,R]$ 交集为空,那么直接 `return`。不用 `if` 判断。
by __uint256_t @ 2022-02-11 09:45:10


```cpp #include<bits/stdc++.h> using namespace std; int a[500005],sum[2000005],n,q; int x,y,z; void build(int o,int L,int R){ if(L==R){ sum[o]=a[L]; return ; } int m=(L+R)/2; build(o*2,L,m); build(o*2+1,m+1,R); sum[o]=sum[o*2]+sum[o*2+1]; } void update(int o,int L,int R){ if(y<L||y>R)return; if(L==R&&L==y){ sum[o]+=z; return ; } int m=(L+R)/2; update(o*2,L,m); update(o*2+1,m+1,R); sum[o]=sum[o*2]+sum[o*2+1]; } int query(int o,int L,int R){ if(z<L||y>R)return 0; if(y<=L && R<=z){ return sum[o]; } int ans=0; int m=(L+R)/2; ans=ans+query(o*2,L,m); ans=ans+query(o*2+1,m+1,R); return ans; } int main(){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,1,n); for(int i=1;i<=q;i++){ scanf("%d%d%d",&x,&y,&z); if(x==1) update(1,1,n); else printf("%d\n",query(1,1,n)); } return 0; } ```
by __uint256_t @ 2022-02-11 09:45:31


Thanks
by Beep_Monkey @ 2022-02-11 11:30:34


|