【模板】线段树
2016-11-15 21:35
253 查看
线段树 处理区间问题的高级数据结构
听说树状数组能做(树状数组我不会啊QAQ )的线段树都能做,就丢个线段树吧QAQ
快NOIP了还是好弱怎么办 急在线等
NOIP Loiers RP ++!!
听说树状数组能做(树状数组我不会啊QAQ )的线段树都能做,就丢个线段树吧QAQ
快NOIP了还是好弱怎么办 急在线等
NOIP Loiers RP ++!!
void up(int p)//更新数据 { tree[p].sum = tree[p<<1].sum + tree[p<<1|1].sum; tree[p].max = max(tree[p<<1].max,tree[p<<1|1].max); tree[p].min = min(tree[p<<1].min,tree[p<<1|1].min); } void push(int p)//标记下放 { tree[p<<1].sum += tree[p].add * (tree[p<<1].r - tree[p<<1].l + 1); tree[p<<1].add += tree[p].add; tree[p<<1|1].sum += tree[p].add * (tree[p<<1|1].r - tree[p<<1|1].l + 1); tree[p<<1|1].add += tree[p].add; tree[p].add = 0; } void build(int p,int l,int r)//建树 { tree[p].l = l; tree[p].r = r; if(l == r) { tree[p].min = tree[p].max = tree[p].sum = num[l]; return ; } int mid = (l + r) >> 1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); up(p); } void change_qujian(int p,int l,int r,int v)//区间修改 { if(l <= tree[p].l && tree[p].r <= r) { tree[p].sum += v * (tree[p].r - tree[p].l +1); tree[p].max += v; tree[p].min += v; tree[p].add += v; return; } push(p); int mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid ) change(p<<1,l,r,v); if(mid < r) change(p<<1|1,l,r,v); up(p); } void change_dian(int p,int a,int x)//单点修改 { if(a==tree[p].l&&tree[p].r==a) { tree[p].sum+=x; tree[p].add+=x; return; } push(p); int mid = (tree[p].l+tree[p].r)/2; if(a <= mid) change(p*2,a,x); if(mid < a) change(p*2+1,a,x); up(p); } ll ask(int p,int l)//单点查询 { if(l == tree[p].l && tree[p].r == l) { return tree[p].sum; } push(p); int mid = (tree[p].l + tree[p].r)/2; ll ans = 0; if(l <= mid) ans += ask(p*2,l); if(mid < l) ans += ask(p*2+1,l); return ans; } ll ask_min(int p,int l,int r)//区间最小值 { if(l <= tree[p].l && tree[p].r <= r) { return tree[p].min; } push(p); int mid = (tree[p].l + tree[p].r) >> 1; ll ans = 21474836472333333; if(l <= mid) ans = min(ans,ask_min(p<<1,l,r)); if(mid < r) ans = min(ans,ask_min(p<<1|1,l,r)); return ans; } ll ask_max(int p,int l,int r)//区间最大值 { if(l <= tree[p].l && tree[p].r <= r) { return tree[p].max; } push(p); int mid = (tree[p].l + tree[p].r) >> 1; ll ans = 0; if(l <= mid) ans = max(ans,ask_max(p<<1,l,r)); if(mid < r) ans = max(ans,ask_max(p<<1|1,l,r)); return ans; } ll ask_sum(int p,int l,int r)//区间求和 { if(l <= tree[p].l && tree[p].r <= r) { return tree[p].sum; } push(p); int mid = (tree[p].l + tree[p].r) >> 1; ll ans = 0; if(l <= mid) ans += ask_sum(p<<1,l,r); if(mid < r) ans += ask_sum(p<<1|1,l,r)); return ans; }
相关文章推荐
- 线段树模板(点修改 ,区间查询)
- 线段树 扫描线求矩阵面积并的模板(zz)
- 杭电5443 线段树模板
- 算法模板——线段树之Lazy标记
- 线段树单点更新模板-杭电1166
- 洛谷 P3372【模板】线段树 1
- 线段树染色模板,用于颜色较少的情况。 POJ 2777
- POJ 3264 线段树模板题
- 简单线段树模板
- P3372 【模板】线段树 1
- 线段树模板
- 形形色色的线段树练习——codevs线段树练习1-5:线段树,树状数组及分块模板
- 线段树模板
- HDU1823-Luck and Love-二维线段树(模板)
- hdu1166 敌兵布阵+线段树模板题+单点修改
- LA 2191电位计(线段树模板题)
- 线段树模板
- SDUT 2880 Devour Magic(线段树lazy和set标记模板)
- 【线段树】线段树模板 胡浩版
- 线段树模板