2024. 1. 24. 15:53ใCoding Test/BOJ
๐๋ฌธ์ ๋ณด๋ฌ๊ฐ๊ธฐ
๐จ๐ปํ์ด ๊ณผ์
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ(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;
}
'Coding Test > BOJ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[BOJ] 2638๋ฒ | ์น์ฆ (C++) (0) | 2024.02.01 |
---|---|
[BOJ] 3055๋ฒ | ํ์ถ (C++) (1) | 2024.01.31 |
[BOJ] 2637๋ฒ | ์ฅ๋๊ฐ ์กฐ๋ฆฝ (C++) (0) | 2023.12.21 |
[BOJ] 11779๋ฒ | ์ต์๋น์ฉ ๊ตฌํ๊ธฐ 2 (C++) (1) | 2023.12.20 |
[BOJ] 2623๋ฒ | ์์ ํ๋ก๊ทธ๋จ (C++) (1) | 2023.12.19 |