ํ๋ํฐ๋5 : ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ๋ฌธ์ ์ด๋ค.
์๊ฐ
|0|1|2|3|4|5|6| |:|:|:|:|:|:|:| |4|1|7|5|2|9|8|
์ ๋ ฅ๊ฐ์ด ์ด๋ ๊ฒ ์ฃผ์ด์ง๋ค๊ณ ์๊ฐํด๋ณด์. ์ด ์ํ์์ 3~6๊น์ง์ ์ต์๊ฐ์ ๊ตฌํ๋ ๊ฒ์, ๋จ์ํ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํด๋ ์ผ๋ก ํ ์ ์๋ค. ํ์ง๋ง ์ด๋ฌํ ํ์ธ(์ฟผ๋ฆฌ)๊ฐ ๋ง์์ง๋ค๋ฉด, ๊ธ๊ฒฉํ๊ฒ ์๊ฐ ๋ณต์ก๋๊ฐ ์ฌ๋ผ๊ฐ๋ค. ๋ฐ๋ผ์ ์ด ๋ฌธ์ ์์ ์ ์ํ๋ m(100000) ๊ฐ์ ๋ํด์ n(100000)์ ๋ชจ๋ ํ์ธํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ฐ๋ค๋ฉด ๋ฌธ์ ๋ฅผ ํ ์ ์๋ค.()
๋ฌธ์ ์ ์์ธ
๊ทธ๋ ๋ค๋ฉด ์ด๋ ๋ถ๋ถ์์ ์ฐ์ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ ์ง ์๊ฐํด๋ณด์. ๊ฐ์ฅ ํฐ ๋ถ๋ถ์ ํ๋จ์ ์ค๋ณต์ผ๋ก ํ๋ค๋ ๊ฒ์ด๋ค. 03๊น์ง์ ์ต์๊ฐ์ ๊ตฌํ๋ ๊ฒ๊ณผ, 14๊น์ง์ ์ต์๊ฐ์ ๊ตฌํ๋ ๊ณผ์ ์๋ 1~3๊น์ง์ ์ต์๊ฐ์ ๋น๊ตํ๋ ๊ณผ์ ์ด ์ค๋ณต๋๋ค. ๊ทธ๋ ๋ค๋ฉด, ์ฒ์์ ์ฃผ์ด์ง index๋ฅผ ๋๋์ด, ๊ทธ ๋๋ ๊ตฌ๊ฐ์ ๋ํด ์ต์๊ฐ์ ๊ตฌํด๋์ผ๋ฉด ์ด๋จ๊น?
์ด๋ป๊ฒ ๋๋๊น?
๋๋๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค๊ณ ๋ ํ์๋, ์ด๋ป๊ฒ ํ๋ฉด ์ ๋๋ ์ ์์ ์ง์ ๋ํด ๊ณ ๋ฏผํ๋ค. ์ด ๋ถ๋ถ์ ํธ๋ฆฌ๊ฐ ๊ฐ์ฅ ์ฉ์ดํ๋ค. ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ์๋ฃ๊ตฌ์กฐ ์ค, ํ์์ ์์ด ์๊ฐ๋ณต์ก๋๊ฐ log์ด๋ค. ๋๋๋ ๋ฐฉ๋ฒ์ ์๊ฐ ๋ณด๋ค ๊ฐ๋จํ๋ค.
Tree ๊ตฌ์กฐ
ํธ๋ฆฌ์ ๊ตฌ์กฐ๋ ๋ชจ์์ ๋ณํ๋ฅผ ๊ฐ์ง๋ ๊ฒ์ด๋ค. ์ฐ๋ฆฌ๊ฐ ๋ณดํต ๊ฐ์ง๋ ์ ํ ๋ฆฌ์คํธ๋ฅผ ์กฐ๊ธ ๋ฐ๊พธ์ด ์๊ฐํ๋ฉด ์ฝ๊ฒ ํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
์ด๋ ๊ฒ 2์ ์ ๊ณฑ์๋งํผ์ ๊ฐ์๋ฅผ ์๋์ชฝ์ผ๋ก ์ฎ๊ธฐ๋ฉด์ ์์ผ๋ฉด ํธ๋ฆฌ ๊ตฌ์กฐ๊ฐ ๋๋ค. ์ด ๋, ์ค์ํ ๊ฒ์ ๊ฐ์ฅ ์์ธต์ผ๋ก ๋ถํฐ ์๋๋ก ๋ด๋ ค์ค๋๋ฐ ๊ทธ index๋ค์ ๊ด๊ณ๋ฅผ ์๋ ๊ฒ์ด๋ค. ์ ๋ณด๋ฉด, 1์์ 2, 3์ , ๊ณผ ๊ฐ๋ค. ์ผ์ชฝ ํธ๋ฆฌ, ์ค๋ฅธ์ชฝ ํธ๋ฆฌ๋ก ๊ฐ๋ ๊ด๊ณ๋ ๊ณ์ ์ผ๊ด์ฑ์ ๊ฐ์ง๋ค.
Segment Tree
๊ทธ๋ ๋ค๋ฉด ์ด๋ฒ์๋ ์ด ํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ด ๋ฌธ์ ์ ๋ง๋ ๋ชจ์์ผ๋ก ๋ฐ๊พธ์ด ๋ณด์. ์ฐ๋ฆฌ๋ ์ต์๊ฐ์ ๋ฏธ๋ฆฌ ์ ์ฅํ๊ธฐ ์ํด ํธ๋ฆฌ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ํ๋๋ฐ, ๊ทธ ๊ตฌ์กฐ๋ฅผ ์๋์ ๊ฐ์ด ๋ง๋ค์ด์ ์๊ฐํด๋ณด์.
๊ธฐ๋ณธ์ ์ธ ํธ๋ฆฌ๊ตฌ์กฐ๋ ๊ฐ์ง๋ง ์ถ๊ฐ๋ ๋ณ์๊ฐ ์๋ค. ๊ทธ๊ฒ์ index์ ์์๊ณผ ๋์ ๋ํ๋ด๋ startend ๋ณ์์ด๋ค. ์ด๋ ๊ฒ ๋๋์๋ค๊ณ ๊ฐ์ ํ๊ณ , 25๊น์ง์ ์ต์๊ฐ์ ์ป๊ธฐ์ํด ์กฐ์ฌํด์ผ ํ๋ Node์ ๊ฐ์๋ฅผ ํ์
ํด๋ณด์.
์ด๋ ๊ฒ 3๊ฐ์ ๊ฐ๋ง ์กฐ์ฌํ๋ฉด ์ต์๊ฐ์ ์ป์ ์ ์๋ค! ์ด ๋ ๋ฐ์ํ๋ ์๊ฐ ๋ณต์ก๋๋ ์ด๋ค. depth๊ฐ ๋ด๋ ค๊ฐ ์๋ก ๋ฐ์ฉ ์กฐ์ฌ๋ฅผ ๋ ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
tree์ ํ์ํ node ์
์ ์์์์ ์ด 7๊ฐ์ ์์๋ฅผ ๋ฃ๊ธฐ ์ํด ํ์ํ node์ ๊ฐ์๋ ์ด 13๊ฐ ์ด๋ค. ์ด 13๊ฐ๋ฅผ ๋ค ๋ฃ๊ธฐ ์ํด ํ์ํ ํธ๋ฆฌ์ ๊น์ด๋ ์ด 4์ด๋ค. ์ด ๊ฐ์ ์ป๊ธฐ ์ํ ์์์ ๋ค์๊ณผ ๊ฐ๋ค.
๋ณดํต์ tree๋ input์ผ๋ก ๋ค์ด์ค๋ ์์์ ๊ฐ์์ ํธ๋ฆฌ์ node๋ฒํธ๊ฐ ์ผ์นํ์ง๋ง, ์ด ๊ฒฝ์ฐ๋ depth๊ฐ 1๊ฐ ์ถ๊ฐ๋๋ฏ๋ก 1์ ๋ํด์ฃผ์ด์ผ ํ๋ค. ์ด๊ฒ์ ์ฝ๋๋ก ๊ตฌํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
h = ceil(log2(n))+1;
treeSize = (1 << h);
<<
์ shift ์ฐ์ฐ์๋ก, 2์ง ์ฐ์ฐ์ ํ ๋, ์๋ฆฌ์๋ฅผ ์ฌ๋ ค์ฃผ๋ ์ญํ ์ ํ๋ค.
init (์ด๊ธฐํ)
์ฒ์์ input์ ๋ฐ๊ณ ์, ๊ฐ์ฅ ๋จผ์ ํด์ผํ๋ ์ผ์, input์ tree์์ ๋ฃ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฐ๋ฐ ์ฐ๋ฆฌ๊ฐ ์ค๊ณํ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์๊ฐํด๋ณด๋ฉด, ์ด ์น๊ตฌ๋ ์๋ node๊ฐ ๊ฒฐ์ ๋ ๋ค์ ์์ ๋ ธ๋๊ฐ ๊ฒฐ์ ๋ ์ ์๋ค. ์ฌ๊ท๋ก ์ง๋ฉด ํด๊ฒฐ๋ ๊ฒ์ด๋ค.
void init(vector<int>& input, vector<int>& tree, int node, int start, int end){
if (start == end) {
tree[node] = input[start];
return;
}
init(input, tree, 2*node, start, (start+end)/2);
init(input, tree, 2*node+1, (start+end)/2+1, end);
tree[node] = min(tree[2*node], tree[2*node+1]);
return;
}
init ํจ์์ argument๋ก๋ input ๋ฒกํฐ, tree ๋ฒกํฐ, ๋ด๊ฐ ๊ธฐ๋กํ node์ index, ์ฒ์ node๊ฐ ์ปค๋ฒํ๊ฒ ๋ index์ ์์๊ณผ ๋์ด ํ์ํ๋ค. ๊ทธ ๋ค๋ก๋ ์๊น ํธ๋ฆฌ ๊ตฌ์กฐ์์ ๋ณธ ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ๋ ธ๋๋ก ๊ฐ๋ ํจ์ ๊ด๊ณ์ ๋ฐ๋ผ initํจ์๋ฅผ ๊ณ์ ์ํํ๋ฉด ๋๋ค. ์ข ๋ฃ์กฐ๊ฑด์, ๊ทธ๋ฆผ์์ ๋ณด์๋ฏ์ด start์ end๊ณผ ๊ฐ์์ง๋ ์ง์ ์์ input์ start ํด๋นํ๋ index์ ๊ฐ์ ๋ฃ์ด์ค๋ค.
find
์ ์ฅ๋ ์๋ฃ๊ตฌ์กฐ์์ ์ฐพ๋ ๊ณผ์ ์ด๋ค. ๋ด๊ฐ ์ฐพ์ผ๋ ค๊ณ ํ๋ ๋ฒ์์ left
, right
๋ผ ํ๊ณ , ๋ด๊ฐ ์ฒ์์ ํ์์ ์์ํ ๋
ธ๋์ ๋ฒํธ๋ฅผ node
, ๊ทธ ๋
ธ๋๊ฐ ์ปค๋ฒํ๋ index์ ๋ฒ์๋ฅผ start
, end
๋ผ ํ์. tree์ ๊ฐ์ฅ ์๋ถํฐ ํ์์ ์์ํ ๋, ๋ฒ์์ ๊ฑธ๋ฆฌ๋ ๋
์๋ค๋ง ๋น๊ต์ ๋์์ด ๋์ด์ผ ํ๋ค. ์ด๋ฐ ๋ฒ์๋ฅผ ๋ฐ์ ธ๋ณด๋ฉด ์ด 3๊ฐ์ง๋ก ๋๋ ์ ์๋ค.
left
,right
์ฌ์ด์ ํ์ฌ ๋ ธ๋์ ์ปค๋ฒ๋ฒ์๊ฐ ๋ค์ด์จ๋ค.- ํ๋ณด๋ก ์ ์ ํ๋ค.
left
,right
์ ํ์ฌ ๋ ธ๋์ ์ปค๋ฒ๋ฒ์๊ฐ ์ ํ ๊ฒน์น์ง ์๋๋ค.- ๋ฒ๋ฆฐ๋ค.
- ์ ๋งคํ๊ฒ ๊ฑธ์น๋ค.
- ๋ ๊น์ด ๋ค์ด๊ฐ์ ์กฐ์ฌํ๋ค.
์ด ๊ณผ์ ์ ๊ตฌํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
int findMin(vector<int>& tree, int node, int start, int end, int left, int right){
if (left > end || right < start) {
return INF;
} else if (left <= start && end <= right){
return tree[node];
}
int a = findMin(tree, 2*node, start, (start+end)/2, left, right);
int b = findMin(tree, 2*node+1, (start+end)/2+1, end, left, right);
return min(a, b);
}
Code
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
const int INF = 1111111111;
void init(vector<int>& input, vector<int>& tree, int node, int start, int end){
if (start == end) {
tree[node] = input[start];
return;
}
init(input, tree, 2*node, start, (start+end)/2);
init(input, tree, 2*node+1, (start+end)/2+1, end);
tree[node] = min(tree[2*node], tree[2*node+1]);
return;
}
int findMin(vector<int>& tree, int node, int start, int end, int left, int right){
if (left > end || right < start) {
return INF;
} else if (left <= start && end <= right){
return tree[node];
}
int a = findMin(tree, 2*node, start, (start+end)/2, left, right);
int b = findMin(tree, 2*node+1, (start+end)/2+1, end, left, right);
return min(a, b);
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int n, m;
cin >> n >> m;
int h = int(ceil(log2(n)))+1;
int treeSize = (1 << h);
vector<int> tree(treeSize, INF);
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
init(a, tree, 1, 0, n-1);
for (int i = 0; i < m; i++) {
int left, right;
cin >> left >> right;
cout << findMin(tree, 1, 0, n-1, left-1, right-1) << '\n';
}
}