题目连接:
http://poj.org/problem?id=3264
题目大意:
有n个数从1开始编号,问在指定区间内,最大数与最小数的差值是多少?
解题思路:
在节点中存储max,min,然后查询指定区间的max、min。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 200010; 6 const int INF = 0x3f3f3f3f; 7 struct node 8 { 9 int L, R; 10 int Min, Max; 11 int Mid() 12 { 13 return (L + R) / 2; 14 } 15 }; 16 node tree[maxn]; 17 int Min, Max; 18 19 void build(int root, int l, int r) 20 { 21 tree[root].L = l; 22 tree[root].R = r; 23 tree[root].Min = INF; 24 tree[root].Max = -INF; 25 if (l == r) 26 return ; 27 build (2*root+1, l, tree[root].Mid()); 28 build (2*root+2, tree[root].Mid()+1, r); 29 } 30 void insert (int root, int x, int s) 31 { 32 tree[root].Min = min (tree[root].Min, s); 33 tree[root].Max = max (tree[root].Max, s); 34 if (tree[root].L == tree[root].R) 35 return ; 36 if (x <= tree[root].Mid()) 37 insert (2*root+1, x, s); 38 else if (x > tree[root].Mid()) 39 insert (2*root+2, x, s); 40 } 41 void query (int root, int s, int e) 42 { 43 if (tree[root].L == s && tree[root].R == e) 44 { 45 Min = min (Min, tree[root].Min); 46 Max = max (Max, tree[root].Max); 47 return ; 48 } 49 if (e <= tree[root].Mid()) 50 query (2*root+1, s, e); 51 else if (s > tree[root].Mid()) 52 query (2*root+2, s, e); 53 else 54 { 55 query (2*root+1, s, tree[root].Mid()); 56 query (2*root+2, tree[root].Mid()+1, e); 57 } 58 } 59 int main () 60 { 61 int n, q, num; 62 while (scanf ("%d %d", &n, &q) != EOF) 63 { 64 build(0, 1, n); 65 for (int i=1; i<=n; i++) 66 { 67 scanf ("%d", &num); 68 insert (0, i, num); 69 } 70 while (q --) 71 { 72 int s, e; 73 scanf ("%d %d", &s, &e); 74 Min = INF; 75 Max = -INF; 76 query (0, s, e); 77 printf ("%d ", Max - Min); 78 } 79 } 80 return 0; 81 }