๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ
728x90
๐Ÿ”—๋ฌธ์ œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
 

2357๋ฒˆ: ์ตœ์†Ÿ๊ฐ’๊ณผ ์ตœ๋Œ“๊ฐ’

N(1 ≤ N ≤ 100,000)๊ฐœ์˜ ์ •์ˆ˜๋“ค์ด ์žˆ์„ ๋•Œ, a๋ฒˆ์งธ ์ •์ˆ˜๋ถ€ํ„ฐ b๋ฒˆ์งธ ์ •์ˆ˜๊นŒ์ง€ ์ค‘์—์„œ ์ œ์ผ ์ž‘์€ ์ •์ˆ˜, ๋˜๋Š” ์ œ์ผ ํฐ ์ •์ˆ˜๋ฅผ ์ฐพ๋Š” ๊ฒƒ์€ ์–ด๋ ค์šด ์ผ์ด ์•„๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์™€ ๊ฐ™์€ a, b์˜ ์Œ์ด M(1 ≤ M ≤ 100

www.acmicpc.net

 

๐Ÿ‘จ‍๐Ÿ’ปํ’€์ด ๊ณผ์ •

 

์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ(Segment Tree) ์ฒซ ์ž…๋ฌธ ๋ฌธ์ œ๋กœ ํ’€์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ์‹œ๋„๊ณ , ์กฐ๊ธˆ ๋ณ€ํ˜•๋œ ๋ฌธ์ œ์ธ์ง€๋ผ ๊ฒฐ๊ตญ ๋‹ค๋ฅธ ๋ถ„๋“ค์˜ ํ’€์ด๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ํ’€์—ˆ์ง€๋งŒ, ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋ผ๋Š” ๊ฐœ๋…๊ณผ ์–ด๋Š์ •๋„ ์นœ์ˆ™ํ•ด์ง„ ๊ทธ๋Ÿฐ ๊ณ„๊ธฐ๊ฐ€ ์•„๋‹ˆ์—ˆ๋‚˜ ์‹ถ์Šต๋‹ˆ๋‹ค.

 

๋ฐฑ์ค€ ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ๋Š๋‚€ ๊ฑฐ์ง€๋งŒ, ๋‹ค์–‘ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋“ค์„ ์ ‘ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ ๋˜๊ฒŒ ์ข‹์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์•„์ง ์ ‘ํ•ด๋ณด๊ณ  ํ’€์–ด๋ด์•ผ ํ•  ๋ฌธ์ œ๋“ค์ด ๋งŽ์ง€๋งŒ ํ•˜๋‚˜์”ฉ ์ฒœ์ฒœํžˆ ํ•ด๋ด์•ผ์ฃ . ํ’€์ด ๊ณผ์ •์„ ์ ๋Š” ๊ตฌ๊ฐ„์ธ๋ฐ ์ œ ๋Š๋‚€์ ์„ ์ ๊ณ  ์žˆ์—ˆ๋„ค์š”.

 

ํŠœํ”Œ(Tuple)์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” pair<int, int>๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ตœ์†Ÿ๊ฐ’๊ณผ ์ตœ๋Œ“๊ฐ’์„ ๊ฐ€์ง€๋„๋ก ๋งŒ๋“ค์—ˆ๊ณ , vector<pair<int, int>>๋ฅผ ํ†ตํ•ด ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ๊ฐ„ ํ•ฉ์„ ๋น ๋ฅด๊ฒŒ ๊ตฌํ•˜๊ธฐ ์œ„ํ•œ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์ผ๋ฐ˜์ ์ธ๋ฐ, ์ด ๋ฌธ์ œ๋Š” ๋ง์…ˆ์„ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์†Ÿ๊ฐ’๊ณผ ์ตœ๋Œ“๊ฐ’์„ ๊ณจ๋ผ์ฃผ๋Š” ๋กœ์ง์œผ๋กœ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

โœ๏ธ ์†Œ์Šค ์ฝ”๋“œ ๋ฐ ๊ฒฐ๊ณผ

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;
using Data = pair<int, int>;    // <min, max>

#define FAST_IO ios::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL);
#define INF 1000000001

vector<Data> SegmentTree;
vector<int> Array;

int CreateMinSegmentTree(int node, int start, int last)
{
    if (start == last)
        return SegmentTree[node].first = Array[start];

    int mid = (start + last) / 2;
    int leftChild = node * 2, rightChild = node * 2 + 1;

    int leftChildMinInteger = CreateMinSegmentTree(leftChild, start, mid);
    int rightChildMinInteger = CreateMinSegmentTree(rightChild, mid + 1, last);

    return SegmentTree[node].first = min(leftChildMinInteger, rightChildMinInteger);
}

int CreateMaxSegmentTree(int node, int start, int last)
{
    if (start == last)
        return SegmentTree[node].second = Array[start];

    int mid = (start + last) / 2;
    int leftChild = node * 2, rightChild = node * 2 + 1;

    int leftChildMaxInteger = CreateMaxSegmentTree(leftChild, start, mid);
    int rightChildMaxInteger = CreateMaxSegmentTree(rightChild, mid + 1, last);

    return SegmentTree[node].second = max(leftChildMaxInteger, rightChildMaxInteger);
}

int FindMinInteger(int node, int start, int last, int left, int right)
{
    if (last < left or right < start)
        return INF;
    
    if (left <= start and last <= right)
        return SegmentTree[node].first;
    
    int mid = (start + last) / 2;
    int leftChild = node * 2, rightChild = node * 2 + 1;

    int leftMinInteger = FindMinInteger(leftChild, start, mid, left, right);
    int rightMinInteger = FindMinInteger(rightChild, mid + 1, last, left, right);

    return min(leftMinInteger, rightMinInteger);
}

int FindMaxInteger(int node, int start, int last, int left, int right)
{
    if (last < left or right < start)
        return -INF;
    
    if (left <= start and last <= right)
        return SegmentTree[node].second;
    
    int mid = (start + last) / 2;
    int leftChild = node * 2, rightChild = node * 2 + 1;

    int leftMaxInteger = FindMaxInteger(leftChild, start, mid, left, right);
    int rightMaxInteger = FindMaxInteger(rightChild, mid + 1, last, left, right);

    return max(leftMaxInteger, rightMaxInteger);
}

int main()
{
    FAST_IO
    int N, M;
    cin >> N >> M;

    Array.resize(N);
    for (int i = 0; i < N; i++)
        cin >> Array[i];
    
    int treeHeight = static_cast<int>(ceil(log2(N)));
    int treeSize = 1 << (treeHeight + 1);

    SegmentTree.resize(treeSize);
    CreateMinSegmentTree(1, 0, N - 1);
    CreateMaxSegmentTree(1, 0, N - 1);

    int from, to;
    for (int i = 0; i < M; i++)
    {
        cin >> from >> to;
        int minInteger = FindMinInteger(1, 0, N - 1, from - 1, to - 1);
        int maxInteger = FindMaxInteger(1, 0, N - 1, from - 1, to - 1);

        cout << minInteger << " " << maxInteger << "\n";
    }

    return 0;
}

 

 

728x90
๋ฐ˜์‘ํ˜•