POJ3264Balanced Lineup(线段树)

题目大意就是说给你一个长度为N的区间,并给定区间每个点的值,求Q次询问区间<x,y>之间的最大值与最小值的差

 

这是我第一道用线段树做的题目^_^

采用线段树记录区间x,y的最大值用最小值,每一次询问的复杂度就是logN总复杂度就是QlogN,详见代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define MAX(a,b) (a)>(b)?(a):(b)
 5 #define MIN(a,b) (a)<(b)?(a):(b)
 6 #define MAXN 50010
 7 using namespace std;
 8 
 9 struct node
10 {
11     int x,y;
12     int max,min;
13 }ma[3*MAXN];
14 int H[MAXN],N,Q;
15 
16 void build_tree(int index,int x,int y)//建树,在回溯时给max与min赋值
17 {
18     ma[index].x = x;
19     ma[index].y = y;
20     if(x == y)
21     {
22         ma[index].max=ma[index].min=H[y];
23         return;
24     }
25     int mid = (x+y)/2;
26     build_tree(index*2, x, mid);//构造左子树
27     build_tree(index*2+1, mid+1, y);//构造右子树
28     ma[index].max = MAX(ma[index*2].max, ma[index*2+1].max);//此区间的最大值就是两颗子树最大值的最大值
29     ma[index].min = MIN(ma[index*2].min, ma[index*2+1].min);
30 }
31 
32 int search_max(int index,int x,int y)//找到区间最大值
33 {
34     if(ma[index].x==x && ma[index].y==y)
35         return ma[index].max;
36     int mid = (ma[index].x+ma[index].y)/2;
37     if(x > mid)                           //在右子树中
38         return search_max(index*2+1, x, y);
39     if(y <= mid)                          //在左树中
40         return search_max(index*2, x, y);
41                                         //在两颗子树之间
42     int L = search_max(index*2, x, mid);
43     int R = search_max(index*2+1, mid+1, y);
44     return MAX(L,R);
45 }
46 
47 int search_min(int index,int x,int y)//找到区间最小值
48 {
49     if(ma[index].x==x && ma[index].y==y)
50         return ma[index].min;
51 
52     int mid = (ma[index].x+ma[index].y)/2;
53     if(x > mid)
54         return search_min(index*2+1, x, y);
55     if(y <= mid)
56         return search_min(index*2, x, y);
57     int L = search_min(index*2, x, mid);
58     int R = search_min(index*2+1, mid+1, y);
59     return MIN(L,R);
60 
61 }
62 
63 int main()
64 {
65     while(~scanf("%d%d",&N,&Q))
66     {
67         int i,x,y;
68         for(i = 1; i <= N; i ++ ) scanf("%d", &H[i]);
69         build_tree(1, 1, N);
70         for(i = 0; i < Q; i ++ )
71         {
72             scanf("%d%d", &x, &y);
73             printf("%d\n", search_max(1,x,y)-search_min(1,x,y));
74         }
75     }
76     return 0;
77 }

 

posted @ 2013-06-12 01:24  再见~雨泉  阅读(173)  评论(0编辑  收藏  举报