์ธ๊ทธ๋จผํธ ํธ๋ฆฌ
https://www.acmicpc.net/blog/view/9
๋ฐฑ์ค๋ ๊ธ
๋ฐฐ์ด ํฌ๊ธฐ ๊ฒฐ์
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ C++์ ๊ฒฝ์ฐ, vector ์๋ฃํ์ ์ฌ์ฉํ๋๋ฐ python์ผ๋ก ๊ตฌํํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ค. ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ ์ผ๋ง๋ ๋์ด์ผ ํ ์ง ๊ฐ๋ ํ๊ธฐ ์ํด ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํด๋ณด์.
2์ ์ ๊ณฑ ์๊ฐ ๋ฆฌํ ๋ ธ๋์ ์(n)๋ก ์ฃผ์ด์ง๋ค๋ฉด ( ๋ถ์ํด์ผํ data ๊ฐฏ์๊ฐ 2์ ์ ๊ณฑ ์๋ผ๋ฉด ) ๊ฐ ๋จ๊ณ๋ง๋ค 1/2์ฉ ์ค์ด๋๊ฐ๋ฏ๋ก log(n)์ด ํ์ํ ์ด ๋จ๊ณ(ํ์ดํ)๊ฐ ๋๊ณ ์ ์ฒด ์ธต์ ๊ฐฏ์, ์ฆ ๋์ด(h)๋ log(n)+1์ด ๋๋ค.
์ต์์ ๋ ธ๋๋ถํฐ 2^(0)๊ฐ์ ๋ ธ๋๋ก ์์ํ์ฌ ์ธต์ด ์ฆ๊ฐํ ์๋ก 2์ ์ง์ ๋ํ ์ฆ๊ฐํ๊ธฐ ๋๋ฌธ์ ๊ฝ์ฐฌ ์ด์ค ํธ๋ฆฌ(full binary tree)์ ์ด ๋ ธ๋ ์๋ 2^(0)+2^(1)+...+2^(h-1) (h๋ ๋์ด) ๊ฐ ๋์ด 2^(h)-1 ๊ฐ ์ด๋ค.
h = log(n)+1 ์ด๋ฏ๋ก ํ์ํ ๋ ธ๋์ ์๋ 2^(log(n)+1)-1 ๊ฐ์ด๋ค.
2์ ์ ๊ณฑ ์๊ฐ ์๋ ๊ฒฝ์ฐ๋ ๋๊ฐ์ด ๊ณ์ฐํ ์ ์๋ค. ๋ค๋ง ์ ์๊ฐ ๋์ค์ง ์์ผ๋ฏ๋ก ์ฌ๋ฆผํด์ฃผ๋ฉด ๋๋ค. ์์ ๊ทธ๋ฆผ์ ํ์๋ ํ์ ๋๊ทธ๋ผ๋ฏธ๋ค์ ์กด์ฌํ์ง๋ง ์ฌ์ฉํ์ง ์๋ ๋ฐฐ์ด์ ์์๋ค์ด๋ค.
๋ฐ๋ผ์ ์ฒ์์ tree ๋ฐฐ์ด์ ํฌ๊ธฐ๋ 2^(log(n)+1)-1์ด๊ณ ๋ค์๊ณผ ๊ฐ์ด ์ ์ธํ ์ ์๋ค.
tree_list = [0]*(pow(2,math.ceil(math.log(len(a),2))+1))-1 #a๋ ๋ฐฐ์ด
# math.log(๊ฐฏ์,2) => log(๊ฐฏ์)
# math.ceil => ์ฌ๋ฆผ
# pow(2,์ซ์) => 2^(์ซ์)
์ผ๋จ ํ์๋ ์ต์์ ๊ฐ์ ๊ตฌํ๊ธฐ ์ํด ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ์์ผ๋ฏ๋ก ๋ชจ๋ ๊ฐ์ 0์ผ๋ก ์ด๊ธฐํํ๋ค.
init
์ผ๋จ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์ฃผ์ด์ง ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด์ ์ฑ์์ผํ๋ค. ๋ฐ๋ผ์ init ํจ์๋ฅผ ๋ฐ๋ก ๊ตฌํํ์ฌ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์ฑ์ฐ๊ธฐ๋ก ํ์. init ํจ์๋ 2๊ฐ์ฉ ๊ฒ์ฌํ์ฌ ๋ ์์ ์๋ฅผ ์๋ก ์ฌ๋ฆฌ๋ ํธ๋ฆฌ์ ํํ๋ฅผ ๋์ด์ผํ๋ฏ๋ก ์ฌ๊ทํจ์๋ก ๊ตฌํํ ๊ฒ์ด๋ค. ์ด ๋, ๊ธฐ์ ์ฌ๋ก๋(ํ์ถ ์กฐ๊ฑด์) ๋ฆฌํ๋ ธ๋์ด๋ค.
def init(a, tree, node, start, end):
if start == end:
tree[node-1] = start
else:
init(a,tree,node*2,start,(start+end)//2)
init(a,tree,node*2+1,(start+end)//2+1,end)
if a[tree[node*2-1]]<a[tree[node*2]]:
tree[node-1] = tree[node*2-1]
else:
tree[node-1] = tree[node*2]
ํ๋์ ์์ ๋ฅผ ๊ฐ์ง๊ณ ํด๋น ์ฝ๋๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉฐ ๊ฐ๋ค์ ์ข๋ค๋ณด๋ฉด ์ด๋ป๊ฒ ์ด๋ฐ ์ฝ๋๊ฐ ๊ตฌ์ฑ๋์๋์ง ์๊ฒ์ด๋ค. ํธ๋ฆฌ์๋ ์ฃผ์ด์ง ๋ฐฐ์ด์ ๊ฐ์ด ๋ค์ด๊ฐ๋ ๊ฒ์ด ์๋๋ผ ์ธ๋ฑ์ค๊ฐ ๋ค์ด๊ฐ๋ค. ํ์๋ ์ผ์ ์ ์ธ๊ธํ ๋ฐ์ ๊ฐ์ด ๊ฐ์ฅ ์์ ์ต์๊ฐ์ ์ฐพ๊ธฐ ์ํด ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑํ์๋ค.
query
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์ด์ฉํ์ฌ ์ต์๊ฐ์ ๊ฐ์ ธ์ค๋ ๊ณผ์ ์์ ๋ฐฐ์ด ์ ์ฒด๋ฅผ ๋ฐ์ง์๋ฉด ๋ฐฐ์ด์ 0๋ฒ์งธ index ๊ฐ์ ํด๋นํ๋ ๋ถ๋ถ๋ง ์ดํด๋ณด๋ฉด ๋๋ค. ์ต์์ ๋ ธ๋๊ฐ ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์์๋ก ์ ์ฅ๋์ด์๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง ์ฌ๋ฌ ๋ฒ ๋ค๋ฅธ ๋ฒ์๋ก ์ ๊ทผํ๋ฉด์ ๊ทธ ๋ฒ์์์์ ์ต์๊ฐ์ ์ฐพ์ผ๋ ค๊ณ ํ ๋๋ ์ด๋ป๊ฒ ํด์ผํ ๊น? ๋งค๋ฒ ๋ฒ์์ ํด๋นํ๋ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ๋ฅผ ์๋ก ๋ง๋ค์ด์ ์ฒซ๋ฒ์งธ ์์๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๋ ํ ๋ฐฉ๋ฒ์ด๊ฒ ์ง๋ง ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ๊ฒ์ด๋ค. ๋ฐ๋ผ์ query๋ผ๋ ํจ์๋ฅผ ๋ง๋ค์ด ํด๋น ๋ฒ์์์์ ์ต์๊ฐ์ ๊ณ์ฐํ๋๋ก ํ๋ค.
def query(a,tree,node,start,end,i,j):
if i>end or j<start: # ์ฃผ์ด์ง ๋ฒ์๊ฐ ์ ์ฒด ๋ฒ์์ ์์ ํ ์ํ์ง ์๋๋ค๋ฉด
return -1
if i<=start and end<=j: # ์ฃผ์ด์ง ๋ฒ์๊ฐ ์ ์ฒด ๋ฒ์๋ฅผ ์์ ํ ํฌํจํ๋ค๋ฉด
return tree[node-1] # ํด๋น ๋ฒ์์ ์ต์๊ฐ index๋ฅผ return ํจ
# ์ฃผ์ด์ง ๋ฒ์๊ฐ ์ ์ฒด ๋ฒ์์ ์ํด์๋ค๋ฉด
# ex_) 0~4 index์ ๊ฐ์ด ์ฃผ์ด์ก์ ๋, 1~3 index์ ๋ํ ์ต์๊ฐ์ ๊ตฌํ๊ณ ์ถ์
m1 = query(a,tree,2*node,start,(start+end)//2,i,j) # ์ ์ฒด ๋ฒ์๋ฅผ ๋ฐ์ผ๋ก ์๋ฅธ ๋ฒ์๋ฅผ ๋๊ธฐ๊ณ ์ผ์ชฝ ๋
ธ๋ ๊ฐ์ ๋๊น
m2 = query(a,tree,2*node+1,(start+end)//2+1,end,i,j) # ์ ์ฒด ๋ฒ์๋ฅผ ๋ฐ์ผ๋ก ์๋ฅธ ๋ฒ์๋ฅผ ๋๊ธฐ๊ณ ์ค๋ฅธ์ชฝ ๋
ธ๋ ๊ฐ์ ๋๊น
if m1==-1:
return m2
elif m2==-1:
return m1
else:
if a[m1]<=a[m2]:
return m1
else:
return m2
ํด๋น ๊ทธ๋ฆผ๊ณผ ์ฝ๋๋ฅผ ๊ฐ์ด ์ดํด๋ณด๋ฉด ํด๋น ๊ทธ๋ฆผ์์ 1-4 ์ฌ์ด์ ์ต์๊ฐ์ ์ฐพ๊ณ ์ ํ ๋ ํ์ํ ๋ ธ๋๋
์์ 3๊ฐ์ง ๋ ธ๋์ด๋ค. query ํจ์์ i,j ๋งค๊ฐ๋ณ์๋ฅผ ํตํด 1,4๋ฅผ ๋๊ธฐ๋ฉด ์ฒ์์๋ if๋ฌธ 2๊ฐ๋ฅผ ํต๊ณผํ๊ณ m1,m2๋ฅผ ๊ณ์ฐํ๊ฒ ๋๋ค. ์ด ๋ m1์ 0-2, m2๋ 3-4 index์ ์ต์๊ฐ์ ๊ฐ๊ฐ ๋ฐ์์ค๋ฏ๋ก ๊ทธ๋ฆผ์ 2๋ฒ์งธ ์ธต์ ์๋ฏธํ๋ค๊ณ ๋ณผ ์ ์๋ค. ๋ฐ๋ผ์ ๋งค๊ฐ๋ณ์๋ก ๋๊ฒจ์ง๋ node ๊ฐ๋ ์ด์ ๋ง์ถฐ ๋ฐ๋์๋ค.
m1์ผ๋ก ๊ฐ์ 0-2๋ ๋ if๋ฌธ 2๊ฐ๋ฅผ ํต๊ณผํด์ m1์ด 0-1, m2๊ฐ 2๋ก ์ฃผ์ด์ง๋ค.
๋ค์ m1์ผ๋ก ๋ค์ด๊ฐ๋ฉด m1์ด 0-0, m2๊ฐ 1-1๋ก ๋๋์ด ๊ฐ๊ฐ m1์ ๋ฒ์์ ์ํ์ง ์์ผ๋ฏ๋ก -1, m2๋ ๋ฒ์์ ์ํ๋ฏ๋ก index 1์ ๊ฐ์ด return ๋๋ค. (๋งจ ์๋์ชฝ ์ผ์ชฝ์ ์ฃผํฉ์ 1 ๋ ธ๋) m1,m2 ๊ฐ์ด return ๋์์ผ๋ฏ๋ก ์๋์ if ๋ฌธ์ ํตํด์ ๋น๊ตํด๋ณด๋ฉด m1์ด -1์ด๋ฏ๋ก m2 ๊ฐ์ returnํ๊ฒ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์์์ m1์ index 1์ ๊ฐ์ด๊ณ , m2๋ 2๊ฐ ํด๋น ๋ฒ์์ ์ํ๋ฏ๋ก index 2์ ๊ฐ์ธ๋ฐ ๋๋ค -1์ด ์๋๋ฏ๋ก if๋ฌธ์ 2๊ฐ์ ์กฐ๊ฑด์ ํต๊ณผํ๊ณ ๋ง์ง๋ง else ๋ฌธ์์ 1๊ณผ 2 ์ค ์ฃผ์ด์ง ๋ฐฐ์ด์์ ๋ ์์ ์๋ฅผ ๊ฐ์ง index๊ฐ return ๋๋ค.
์ฌ๊ธฐ๊น์ง ํ๋ฉด ์ฒซ๋ฒ์งธ ๋ฌธ๋จ์์ m1์ ๊ตฌํ ๊ฒ์ด๋ค. ์ด๋ 1-2 ๋ฒ์์ ์ต์๊ฐ์ ๊ตฌํ ๊ฒ์ด๊ณ ๋๊ฐ์ ๋ฐฉ์์ผ๋ก m2๋ ๊ตฌํ๋ฉด m2๋ query ํจ์์ 2๋ฒ์งธ if๋ฌธ์ ํด๋นํ๋ฏ๋ก ํด๋น ๋ ธ๋์ ์๋ index๋ฅผ ๋ฐ๋ก ๋ฐํํ๋ค.
์ด ๋์ ๋น๊ตํด์ ๋ง์ง๋ง ์ต์๊ฐ์ ๊ตฌํ๊ฒ ๋๋ค.
Comment