线段树单点修改区间修改单点查询值区间查询最大值最小值区间和之模板
Posted st-lovaer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树单点修改区间修改单点查询值区间查询最大值最小值区间和之模板相关的知识,希望对你有一定的参考价值。
毕生所学。
1 const int N = 2e5 + 10; 2 #define lson rt << 1 // == rt * 2 左儿子 3 #define rson rt << 1 | 1 // == rt * 2 + 1 右儿子 4 #define int_mid int mid = tree[rt].l + tree[rt].r >> 1 5 int a[N]; // 初始值 6 struct node { 7 int l, r; 8 ll val, lazy; 9 } tree[N * 4]; 10 void push_up(int rt) { 11 //tree[rt].val = min(tree[lson].val, tree[rson].val); 12 //tree[rt].val = max(tree[lson].val, tree[rson].val); 13 tree[rt].val = tree[lson].val + tree[rson].val; 14 } 15 void push_down(int rt) { 16 if (tree[rt].lazy) { 17 tree[lson].lazy += tree[rt].lazy; 18 tree[rson].lazy += tree[rt].lazy; 19 //{ // 维护最大最小值 20 // tree[lson].val += tree[rt].lazy; 21 // tree[rson].val += tree[rt].lazy; 22 //} 23 { // 维护和 24 int l = tree[rt].l, r = tree[rt].r; 25 int mid = l + r >> 1; 26 tree[lson].val += 1ll * (mid - l + 1) * tree[rt].lazy; 27 tree[rson].val += 1ll * (r - mid) * tree[rt].lazy; 28 } 29 tree[rt].lazy = 0; 30 } 31 } 32 void build(int rt, int l, int r) { // 建树 33 tree[rt].l = l, tree[rt].r = r; 34 tree[rt].lazy = 0; 35 if (l == r) { 36 tree[rt].val = a[l]; // 给定一个初始值 37 return; 38 } else { 39 int mid = l + r >> 1; // (l + r) / 2 40 build(lson, l, mid); 41 build(rson, mid + 1, r); 42 push_up(rt); 43 } 44 } 45 46 void update_point(int rt, int pos, ll val) { // 单点更新 47 if (tree[rt].l == tree[rt].r && pos == tree[rt].l) { 48 tree[rt].val += val; 49 return; 50 } 51 int_mid; 52 if (pos <= mid) update_point(lson, pos, val); 53 else update_point(rson, pos, val); 54 push_up(rt); 55 } 56 57 void update_interval(int rt, int l, int r, ll val) { // 区间更新 58 if (l <= tree[rt].l && r >= tree[rt].r) { 59 tree[rt].lazy += val; 60 //tree[rt].val += val; // 维护最大最小值 61 tree[rt].val += 1ll * (tree[rt].r - tree[rt].l + 1) * val; // 维护和 62 return; 63 } 64 push_down(rt); 65 int_mid; 66 if (l <= mid) update_interval(lson, l, r, val); 67 if (r > mid) update_interval(rson, l, r, val); 68 push_up(rt); 69 } 70 71 ll query_point(int rt, int pos) { // 单点查询 72 if (tree[rt].l == tree[rt].r && tree[rt].l == pos) 73 return tree[rt].val; 74 push_down(rt); 75 int_mid; 76 if (pos <= mid) query_point(lson, pos); 77 else query_point(rson, pos); 78 } 79 80 ll query_interval(int rt, int l, int r) { // 区间查询 81 if (l <= tree[rt].l && r >= tree[rt].r) 82 return tree[rt].val; 83 push_down(rt); 84 int_mid; 85 if (r <= mid) return query_interval(lson, l, r); 86 else if (l > mid) return query_interval(rson, l, r); 87 else { 88 //return min(query_interval(lson, l, mid), query_interval(rson, mid + 1, r)); 89 //return max(query_interval(lson, l, mid), query_interval(rson, mid + 1, r)); 90 return query_interval(lson, l, mid) + query_interval(rson, mid + 1, r); 91 } 92 }
以上是关于线段树单点修改区间修改单点查询值区间查询最大值最小值区间和之模板的主要内容,如果未能解决你的问题,请参考以下文章