POJ 3264 Balanced Lineup

学习线段树的第一题。

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

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

 

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

 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 }
代码君

 

你可能感兴趣的:(poj)