线段树模板(二)---区间操作
详解:https://blog.csdn.net/yitongjun/article/details/53193724
一、区间操作,只有add
1 #define MID(l, r) ((l) + ((r) - (l)) / 2) 2 #define lson(o) ((o)<<1) 3 #define rson(o) ((o)<<1|1) 4 typedef long long ll; 5 const int maxn = 1e5 + 10; 6 struct node 7 { 8 int l, r; 9 ll sum, add, mmax, mmin; 10 }tree[maxn * 4]; 11 ll a[maxn]; 12 void pushup(int o) 13 { 14 int lc = lson(o), rc = rson(o); 15 tree[o].sum = tree[lc].sum + tree[rc].sum; 16 tree[o].mmax = max(tree[lc].mmax, tree[rc].mmax); 17 tree[o].mmin = min(tree[lc].mmin, tree[rc].mmin); 18 } 19 void build(int o, int l, int r) 20 { 21 tree[o].l = l; 22 tree[o].r = r; 23 if(l == r) 24 { 25 tree[o].mmax = tree[o].mmin = tree[o].add = tree[o].sum = a[l]; 26 return; 27 } 28 int m = MID(l, r); 29 build(lson(o), l, m); 30 build(rson(o), m + 1, r); 31 pushup(o); 32 //printf("%d %d %d %lld %lld %lld\n", o, l, r, tree[o].add, tree[o].sum, tree[o].mmax); 33 } 34 35 void maintain(int o) 36 { 37 tree[o].mmax = tree[o].mmin = tree[o].sum = 0;//根节点的值存储在add内 38 if(tree[o].r > tree[o].l) 39 { 40 pushup(o); 41 } 42 tree[o].mmin += tree[o].add; 43 tree[o].mmax += tree[o].add; 44 tree[o].sum += tree[o].add * (tree[o].r - tree[o].l + 1); 45 } 46 47 ///[ql, qr] 加上 v 48 int ql, qr; 49 ll v; 50 void update(int o) 51 { 52 if(ql <= tree[o].l && qr >= tree[o].r)tree[o].add += v; 53 else 54 { 55 int m = MID(tree[o].l, tree[o].r); 56 if(ql <= m)update(lson(o)); 57 if(qr > m)update(rson(o)); 58 } 59 maintain(o); 60 } 61 62 ll sum, mmax, mmin; 63 ///[ql, qr]查询 64 /*void query_init() 65 { 66 sum = 0; 67 mmax = -INF; 68 mmin = INF; 69 }*/ 70 void query(int o, ll add) 71 { 72 //DEBUG(o); 73 if(ql <= tree[o].l && qr >= tree[o].r) 74 { 75 sum += tree[o].sum + add * (tree[o].r - tree[o].l + 1); 76 mmin = min(mmin, tree[o].mmin + add); 77 mmax = max(mmax, tree[o].mmax + add); 78 } 79 else 80 { 81 int m = MID(tree[o].l, tree[o].r); 82 if(ql <= m)query(lson(o), add + tree[o].add); 83 if(qr > m)query(rson(o), add + tree[o].add); 84 } 85 }
2、区间操作,只有set
1 #define MID(l, r) ((l) + ((r) - (l)) / 2) 2 #define lson(o) ((o)<<1) 3 #define rson(o) ((o)<<1|1) 4 using namespace std; 5 typedef long long ll; 6 const int maxn = 1e5 + 10; 7 struct node 8 { 9 int l, r; 10 ll sum, Set, mmax, mmin; 11 }tree[maxn * 4]; 12 ll a[maxn]; 13 void pushup(int o) 14 { 15 int lc = lson(o), rc = rson(o); 16 tree[o].sum = tree[lc].sum + tree[rc].sum; 17 tree[o].mmax = max(tree[lc].mmax, tree[rc].mmax); 18 tree[o].mmin = min(tree[lc].mmin, tree[rc].mmin); 19 } 20 void pushdown(int o) 21 { 22 int lc = lson(o), rc = rson(o); 23 if(tree[o].Set >= 0) 24 { 25 tree[lson(o)].Set = tree[rson(o)].Set = tree[o].Set; 26 tree[o].Set = -1; 27 } 28 } 29 void build(int o, int l, int r) 30 { 31 tree[o].l = l; 32 tree[o].r = r; 33 tree[o].Set = -1; 34 if(l == r) 35 { 36 tree[o].mmax = tree[o].mmin = tree[o].sum = 1; 37 return; 38 } 39 int m = MID(l, r); 40 build(lson(o), l, m); 41 build(rson(o), m + 1, r); 42 pushup(o); 43 //printf("%d %d %d %lld %lld %lld\n", o, l, r, tree[o].add, tree[o].sum, tree[o].mmax); 44 } 45 46 void maintain(int o) 47 { 48 if(tree[o].Set >= 0)//优先维护Set 49 { 50 tree[o].mmax = tree[o].mmin = tree[o].Set; 51 tree[o].sum = tree[o].Set * (tree[o].r - tree[o].l + 1); 52 } 53 else if(tree[o].r > tree[o].l)//再维护没有Set的节点 54 { 55 pushup(o); 56 } 57 } 58 59 ///[ql, qr] 设置成v 60 int ql, qr; 61 ll v; 62 void update(int o) 63 { 64 if(ql <= tree[o].l && qr >= tree[o].r)tree[o].Set = v; 65 else 66 { 67 pushdown(o);//向下传递标记 68 int m = MID(tree[o].l, tree[o].r); 69 if(ql <= m)update(lson(o));else maintain(lson(o)); 70 if(qr > m)update(rson(o));else maintain(rson(o)); 71 } 72 maintain(o); 73 } 74 75 ll sum, mmax, mmin; 76 ///[ql, qr]查询 77 /*void query_init() 78 { 79 sum = 0; 80 mmax = -INF; 81 mmin = INF; 82 }*/ 83 void query(int o) 84 { 85 if(tree[o].Set >= 0)//递归边界1,有set标记 86 { 87 sum += tree[o].Set * (min(tree[o].r, qr) - max(tree[o].l, ql) + 1); 88 mmin = min(mmin, tree[o].Set); 89 mmax = max(mmax, tree[o].Set); 90 } 91 else if(ql <= tree[o].l && qr >= tree[o].r)//递归边界2,没有set,且包含于查询区间 92 { 93 sum += tree[o].sum; 94 mmin = min(mmin, tree[o].mmin); 95 mmax = max(mmax, tree[o].mmax); 96 } 97 else 98 { 99 int m = MID(tree[o].l, tree[o].r); 100 if(ql <= m)query(lson(o)); 101 if(qr > m)query(rson(o)); 102 } 103 }
越努力,越幸运