使用線段樹求陣列各區間的最大值,最小值,和
阿新 • • 發佈:2018-12-10
輸入 :第一行輸入n(陣列內元素的個數);第二行 n個數(陣列內的元素);之後每行兩個數x,y(所詢問區間)。
輸出 :分別輸出詢問區間內的最大值,最小值,和。
#include<iostream> #include<algorithm> #include<string> #include<cstdio> #include<cstring> using namespace std; #define inf 0x3f3f3f #define N 200005 double t; int n; int a[N]; int mx[N]; int mn[N]; int sum[N]; void pushup(int rt) { mx[rt] = max(mx[rt * 2], mx[rt * 2 + 1]); mn[rt] = min(mn[rt * 2], mn[rt * 2 + 1]); sum[rt] = sum[rt * 2] + sum[rt * 2 + 1]; } void xtree(int l, int r,int rt) { if (l == r) { mx[rt] = a[l]; mn[rt] = mx[rt]; sum[rt] = a[l]; return; } int mid = (l + r) / 2; xtree(l, mid, rt * 2); xtree(mid + 1, r, rt * 2 + 1); pushup(rt); } //最大值 int Q1(int x, int y, int rt, int l, int r) { if (x <= l && y >= r) return mx[rt]; int mid = (l + r) / 2; int ret = 0; if (x <= mid) ret = max(ret, Q1(x, y, rt * 2, l, mid)); if (y > mid)ret = max(ret, Q1(x, y, rt * 2 + 1, mid + 1, r)); return ret; } //最小值 int Q2(int x, int y, int rt, int l, int r) { if (x <= l &&y >= r) return mn[rt]; int mid = (l + r) >> 1; int ret = inf; if (x <= mid) ret = min(ret, Q2(x, y, rt << 1, l, mid)); if (y > mid)ret = min(ret, Q2(x, y, rt << 1 | 1, mid + 1, r)); return ret; } //和 int arr1(int x, int y, int rt, int l, int r) { if (x == l && y == r) { return sum[rt]; } int mid = (l + r) >> 1; int ret = 0; if (y <= mid) { ret = ret + arr1(x, y, rt * 2, l, mid); } else { if (x > mid) ret = ret + arr1(x, y, rt * 2 + 1, mid + 1, r); else { ret += arr1(x, mid, rt * 2, l, mid); ret += arr1(mid+1, y, rt * 2 + 1, mid + 1, r); } } return ret; } int main() { int x, y; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } xtree(1, n,1); while (1) { scanf("%d%d", &x, &y); if (x == -1) break; cout << Q1(x, y, 1, 1, n) << " " << Q2(x, y, 1, 1, n) << " " << arr1(x, y, 1, 1, n) << endl; } return 0; }