poj3264 Balanced Lineup
题意:
给定Q (1 ≤ Q ≤ 200,000)个数A1,A2 … AQ,,多次求任一区间Ai – Aj中最大数和最小数的差。
思路:
线段树。
实现:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 6 const int MAXN = 65536; 7 const int INF = 0x3f3f3f3f; 8 9 struct node 10 { 11 int maxn, minn; 12 }; 13 14 node data[2 * MAXN - 1]; 15 int n, q, x, y, tmp; 16 17 void init(int n_) 18 { 19 n = 1; 20 while (n < n_) 21 { 22 n *= 2; 23 } 24 for (int i = 0; i < 2 * n - 1; i++) 25 { 26 data[i].maxn = -INF; 27 data[i].minn = INF; 28 } 29 } 30 31 void update(int k, int a) 32 { 33 k += n - 1; 34 data[k].minn = data[k].maxn = a; 35 while (k) 36 { 37 k = (k - 1) / 2; 38 data[k].minn = min(data[2 * k + 1].minn, data[2 * k + 2].minn); 39 data[k].maxn = max(data[2 * k + 1].maxn, data[2 * k + 2].maxn); 40 } 41 } 42 43 int query(int a, int b, int k, int l, int r, int type) 44 { 45 if (r <= a || l >= b) 46 { 47 if (type) 48 return INF; 49 else 50 return -INF; 51 } 52 if (l >= a && r <= b) 53 { 54 if (type) 55 return data[k].minn; 56 else 57 return data[k].maxn; 58 } 59 int x = query(a, b, 2 * k + 1, l, (l + r) / 2, type); 60 int y = query(a, b, 2 * k + 2, (l + r) / 2, r, type); 61 if (type) 62 return min(x, y); 63 return max(x, y); 64 } 65 66 int main() 67 { 68 scanf("%d %d", &n, &q); 69 int n_ = n; 70 init(n); 71 for (int i = 0; i < n_; i++) 72 { 73 scanf("%d", &tmp); 74 update(i, tmp); 75 } 76 for (int i = 0; i < q; i++) 77 { 78 scanf("%d %d", &x, &y); 79 int s = query(x - 1, y, 0, 0, n, 1); 80 int t = query(x - 1, y, 0, 0, n, 0); 81 printf("%d ", t - s); 82 } 83 return 0; 84 }
实现2:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 const int MAXN = 50005; 6 const int INF = 0x3f3f3f3f; 7 int a[MAXN], minn[MAXN * 4], maxn[MAXN * 4], n, m; 8 9 void build(int num, int l, int r) 10 { 11 if (l == r) { maxn[num] = minn[num] = a[l]; return; } 12 int m = l + r >> 1; 13 build(num * 2, l, m); 14 build(num * 2 + 1, m + 1, r); 15 maxn[num] = max(maxn[num * 2], maxn[num * 2 + 1]); 16 minn[num] = min(minn[num * 2], minn[num * 2 + 1]); 17 } 18 19 int query(int num, int l, int r, int x, int y, int type) 20 { 21 if (x <= l && y >= r) return type ? maxn[num] : minn[num]; 22 int m = l + r >> 1; 23 int ans = type ? -INF : INF; 24 if (x <= m) 25 { 26 int tmp = query(num * 2, l, m, x, y, type); 27 ans = type ? max(ans, tmp) : min(ans, tmp); 28 } 29 if (y >= m + 1) 30 { 31 int tmp = query(num * 2 + 1, m + 1, r, x, y, type); 32 ans = type ? max(ans, tmp) : min(ans, tmp); 33 } 34 return ans; 35 } 36 37 int main() 38 { 39 int l, r; 40 scanf("%d %d", &n, &m); 41 for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 42 build(1, 1, n); 43 for (int i = 0; i < m; i++) 44 { 45 scanf("%d %d", &l, &r); 46 printf("%d ", query(1, 1, n, l, r, 1) - query(1, 1, n, l, r, 0)); 47 } 48 return 0; 49 }