1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include <stdio.h> #include <algorithm> #include <cmath> #define MAX 1e9+5 using namespace std; typedef long long ll; ll maxT[2000005] = { 0 }; ll minT[2000005]; ll Tsize,maxTmp,minTmp; void update(ll idx, ll num) { idx += Tsize-1; maxT[idx] = num; minT[idx] = num; while (idx > 1) { idx /= 2; maxT[idx] = max(maxT[idx * 2], maxT[idx * 2 + 1]); minT[idx] = min(minT[idx * 2], minT[idx * 2 + 1]); } } void maxNum(ll left, ll right, ll idx, ll nL, ll nR) { if (nR < left || right < nL) { return; } if (left <= nL&&nR <= right) { maxTmp = max(maxT[idx],maxTmp); return; } ll mid = (nL + nR) / 2; maxNum(left, right, idx * 2, nL, mid); maxNum(left, right, idx * 2 + 1, mid + 1, nR); } void minNum(ll left, ll right, ll idx, ll nL, ll nR) { if (nR < left || right < nL) { return; } if (left <= nL&&nR <= right) { minTmp = min(minT[idx], minTmp); return; } ll mid = (nL + nR) / 2; minNum(left, right, idx * 2, nL, mid); minNum(left, right, idx * 2 + 1, mid + 1 , nR); } int main() { ll n, m; scanf("%lld %lld", &n, &m); for (int i = 1; i < 1000; i++) { if (n < pow(2, i)) { Tsize = (int)pow(2, i); break; } } for (ll i = 1; i <= 2 * Tsize; i++) { minT[i] = 10000000; } for (ll i = 1; i <= n; i++) { ll x; scanf("%lld", &x); update(i, x); } ll a, b; for (ll i = 1; i <= m; i++) { scanf("%lld %lld", &a, &b); maxTmp = 0; minTmp = MAX; maxNum(a, b, 1, 1, Tsize); minNum(a, b, 1, 1, Tsize); printf("%lld %lld\n", minTmp, maxTmp); } } | cs |
'알고리즘 > 세그먼트 트리' 카테고리의 다른 글
11505 구간 곱 구하기 (0) | 2019.02.15 |
---|---|
2042 부분합 (0) | 2019.02.14 |