线段树模板(二)---区间操作

详解: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 }

 

posted @ 2018-08-01 21:38  _努力努力再努力x  阅读(169)  评论(0编辑  收藏  举报