题意:
给定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 int a[MAXN + 1]; 15 node data[2 * MAXN - 1]; 16 int n, q, x, y; 17 18 void init(int n_) 19 { 20 n = 1; 21 while (n < n_) 22 { 23 n *= 2; 24 } 25 for (int i = 0; i < 2 * n - 1; i++) 26 { 27 data[i].maxn = -INF; 28 data[i].minn = INF; 29 } 30 } 31 32 void update(int k, int a) 33 { 34 k += n - 1; 35 data[k].minn = data[k].maxn = a; 36 while (k) 37 { 38 k = (k - 1) / 2; 39 data[k].minn = min(data[2 * k + 1].minn, data[2 * k + 2].minn); 40 data[k].maxn = max(data[2 * k + 1].maxn, data[2 * k + 2].maxn); 41 } 42 } 43 44 int query(int a, int b, int k, int l, int r, int type) 45 { 46 if (r <= a || l >= b) 47 { 48 if (type) 49 return INF; 50 else 51 return -INF; 52 } 53 if (l >= a && r <= b) 54 { 55 if (type) 56 return data[k].minn; 57 else 58 return data[k].maxn; 59 } 60 int x = query(a, b, 2 * k + 1, l, (l + r) / 2, type); 61 int y = query(a, b, 2 * k + 2, (l + r) / 2, r, type); 62 if (type) 63 return min(x, y); 64 return max(x, y); 65 } 66 67 int main() 68 { 69 scanf("%d %d", &n, &q); 70 int n_ = n; 71 init(n); 72 for (int i = 0; i < n_; i++) 73 { 74 scanf("%d", &a[i]); 75 update(i, a[i]); 76 } 77 for (int i = 0; i < q; i++) 78 { 79 scanf("%d %d", &x, &y); 80 int s = query(x - 1, y, 0, 0, n, 1); 81 int t = query(x - 1, y, 0, 0, n, 0); 82 printf("%d\n", t - s); 83 } 84 return 0; 85 }
时间: 2024-10-13 10:33:43