线段树模板
1.
单点更新(add),区间查询
void update(int p,int add,int rt,int l,int r) { if(p>r) return; if(l==r) { tree[rt].sum+=add; return; } else { int m=(l+r)>>1; if(p<=m) update(p,add,lson);//3. 要p的作用哪。只更新一半 。因为下面有Pushup else update(p,add,rson); } Pushup(rt); } int query(int a,int b,int rt,int l,int r) { int ans=0; if(a<=l&&b>=r) { return tree[rt].sum; } else { int m=(l+r)>>1; if(a<=m) ans+=query(a,b,lson); if(b>m) //4. 这地方是r>m果断而不是r>=m ans+=query(a,b,rson); } return ans; }
2.
单点更新,区间最值查询
与1的主要区别就是Max的更新吧。
void Pushup(int rt) { tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); } void build(int rt,int l,int r) { if(l==r) {scanf("%d",&tree[rt].Max);return;}//1. 这地方一开始忘了return else { int m=(l+r)>>1; build(lson); build(rson); } Pushup(rt); } void update(int a,int b,int rt,int l,int r) { if(l==r) {tree[rt].Max=b;return;} else { int m=(l+r)>>1; if(a<=m) update(a,b,lson); if(a>m) update(a,b,rson); } Pushup(rt); } int query(int a,int b,int rt,int l,int r) { int ans=0; if(a<=l&&b>=r) //2. 这地方不留意错写成l==r return 还是自己不理解。 { return tree[rt].Max; } else { int m=(l+r)>>1; if(a<=m) ans=max(ans,query(a,b,lson)); if(b>m) ans=max(ans,query(a,b,rson)); } return ans; }