线段树模板(一)单点更新,区间查询

关于线段树的原理在此不赘述,可参考:https://www.cnblogs.com/AC-King/p/7789013.html

此处用结构体的线段树

一、建树模板:

 1 int a[maxn];
 2 struct node
 3 {
 4     int l, r, mmax, mmin, sum;
 5 }tree[maxn];
 6 void build(int o, int l, int r)
 7 {
 8     tree[o].l = l, tree[o].r = r;
 9     if(l == r)
10     {
11         tree[o].mmax = tree[o].mmin = tree[o].sum = a[l];
12         return;
13     }
14     int m = MID(l, r);
15     int lc = lson(o), rc = rson(o);
16     build(lc, l, m);
17     build(rc, m + 1, r);
18     tree[o].mmax = max(tree[lc].mmax, tree[rc].mmax);
19     tree[o].mmin = min(tree[lc].mmin, tree[rc].mmin);
20     tree[o].sum = tree[lc].sum + tree[rc].sum;
21 }

二、查询区间[ql, qr]中的max,min,sum

 1 int ql, qr;//查询区间[ql, qr]中的max,min,sum
 2 int ans_max, ans_min, ans_sum;
 3 void query_init()//查询前,将全局变量初始化
 4 {
 5     ans_max = -INF;
 6     ans_min = INF;
 7     ans_sum = 0;
 8 }
 9 void query(int o)
10 {
11     if(ql <= tree[o].l && qr >= tree[o].r)//[L, R]包含在[ql, qr]区间内,直接用该节点的信息,达到线段树查询快的操作
12     {
13         ans_max = max(ans_max, tree[o].mmax);
14         ans_min = min(ans_min, tree[o].mmin);
15         ans_sum += tree[o].sum;
16         return;
17     }
18     int m = MID(tree[o].l, tree[o].r);
19     if(ql <= m)query(lson(o));
20     if(qr > m)query(rson(o));
21 }

三、单点更新,a[p] += v

如果需要更新成a[p]  = v,把下面的+=换成=即可

 1 //单点更新,a[p] += v;
 2 int p, v;
 3 void update(int o)
 4 {
 5     if(tree[o].l == tree[o].r)
 6     {
 7         tree[o].mmax += v;
 8         tree[o].mmin += v;
 9         tree[o].sum += v;
10         return;
11     }
12     int m = MID(tree[o].l, tree[o].r);
13     int lc = lson(o), rc = rson(o);
14     if(p <= m)update(lc);
15     else update(rc);
16     tree[o].mmax = max(tree[lc].mmax, tree[rc].mmax);
17     tree[o].mmin = min(tree[lc].mmin, tree[rc].mmin);
18     tree[o].sum = tree[lc].sum + tree[rc].sum;
19 }

四、综上所述

注意开4倍区间

 1 int a[maxn];
 2 struct node
 3 {
 4     int l, r, mmax, mmin, sum;
 5 }tree[maxn];
 6 void build(int o, int l, int r)
 7 {
 8     tree[o].l = l, tree[o].r = r;
 9     if(l == r)
10     {
11         tree[o].mmax = tree[o].mmin = tree[o].sum = a[l];
12         return;
13     }
14     int m = MID(l, r);
15     int lc = lson(o), rc = rson(o);
16     build(lc, l, m);
17     build(rc, m + 1, r);
18     tree[o].mmax = max(tree[lc].mmax, tree[rc].mmax);
19     tree[o].mmin = min(tree[lc].mmin, tree[rc].mmin);
20     tree[o].sum = tree[lc].sum + tree[rc].sum;
21 }
22 int ql, qr;//查询区间[ql, qr]中的max,min,sum
23 int ans_max, ans_min, ans_sum;
24 void query_init()//查询前,将全局变量初始化
25 {
26     ans_max = -INF;
27     ans_min = INF;
28     ans_sum = 0;
29 }
30 void query(int o)
31 {
32     if(ql <= tree[o].l && qr >= tree[o].r)//[L, R]包含在[ql, qr]区间内,直接用该节点的信息,达到线段树查询快的操作
33     {
34         ans_max = max(ans_max, tree[o].mmax);
35         ans_min = min(ans_min, tree[o].mmin);
36         ans_sum += tree[o].sum;
37         return;
38     }
39     int m = MID(tree[o].l, tree[o].r);
40     if(ql <= m)query(lson(o));
41     if(qr > m)query(rson(o));
42 }
43 //单点更新,a[p] += v;
44 int p, v;
45 void update(int o)
46 {
47     if(tree[o].l == tree[o].r)
48     {
49         tree[o].mmax += v;
50         tree[o].mmin += v;
51         tree[o].sum += v;
52         return;
53     }
54     int m = MID(tree[o].l, tree[o].r);
55     int lc = lson(o), rc = rson(o);
56     if(p <= m)update(lc);
57     else update(rc);
58     tree[o].mmax = max(tree[lc].mmax, tree[rc].mmax);
59     tree[o].mmin = min(tree[lc].mmin, tree[rc].mmin);
60     tree[o].sum = tree[lc].sum + tree[rc].sum;
61 }

猜你喜欢

转载自www.cnblogs.com/fzl194/p/9024340.html