学习线段树的第一题。

是的,区间树这个名字更为形象。

线段树适用于和区间统计有关的问题。比如某些数据
可以按区间进行划分,按区间动态进行修改,而且还
需要按区间多次进行查询,那么使用线段树可以达到
较快查询速度。

 

下面的代码是用数组来表示树结构的。

POJ 3264 Balanced Lineup_线段树POJ 3264 Balanced Lineup_ios_02
 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int INF = 0xffffff0;
 8 int minV = INF;
 9 int maxV = -INF;
10 
11 struct Node
12 {
13     int L;
14     int R;
15     int minV, maxV;
16     int Mid()
17     {
18         return (L + R) / 2;
19     }
20 };
21 Node tree[800000 + 10];
22 
23 void BuildTree(int root, int L, int R)
24 {
25     tree[root].L = L;
26     tree[root].R = R;
27     tree[root].minV = INF;
28     tree[root].maxV = -INF;
29     if(L != R)
30     {
31         BuildTree(root * 2 + 1, L, (L+R)/2);
32         BuildTree(root * 2 + 2, (L+R)/2 + 1, R);
33     }
34 }
35 
36 void Insert(int root, int i, int v)
37 {//插入第i个值为v的数
38     if(tree[root].L == tree[root].R)
39     {
40         tree[root].minV = tree[root].maxV = v;
41         return;
42     }
43     tree[root].minV = min(tree[root].minV, v);
44     tree[root].maxV = max(tree[root].maxV, v);
45     if(i <= tree[root].Mid())
46         Insert(root*2 + 1, i, v);
47     else
48         Insert(root*2 + 2, i, v);
49 }
50 
51 void Query(int root, int s, int e)
52 {//查询区间[s,e]上的最大值和最小值然后存放到全局变量里
53     if(tree[root].minV >= minV && tree[root].maxV <= maxV)
54         return;
55     if(tree[root].L == s && tree[root].R == e)
56     {
57         minV = min(tree[root].minV, minV);
58         maxV = max(tree[root].maxV, maxV);
59         return;
60     }
61     if(e <= tree[root].Mid())
62         Query(root*2 + 1, s, e);
63         else if(s > tree[root].Mid())
64                 Query(root*2 + 2, s, e);
65              else
66              {
67                  Query(root*2 + 1, s, tree[root].Mid());
68                  Query(root*2 + 2, tree[root].Mid()+1, e);
69              }
70 }
71 
72 int main(void)
73 {
74     #ifdef LOCAL
75         freopen("3264in.txt", "r", stdin);
76     #endif
77 
78     int n, q;
79     scanf("%d%d", &n, &q);
80     BuildTree(0, 1, n);
81     for (int i = 1; i <= n; ++i)
82     {
83         int j;
84         scanf("%d", &j);
85         Insert(0, i, j);
86     }
87     for (int i = 0; i < q; ++i)
88     {
89         int s, e;
90         scanf("%d%d", &s, &e);
91         minV = INF;
92         maxV = -INF;
93         Query(0, s, e);
94         printf("%d\n", maxV - minV);
95     }
96     return 0;
97 }
代码君