Krafton Jungle/3. TIL

[WEEK04] 세그먼트 트리

munsik22 2025. 4. 8. 22:44

세그먼트 트리란?

세그먼트 트리는 배열의 구간에 대한 정보를 저장하는 트리 자료구조이다. 주로 다음과 같은 경우에 사용된다:

  • 부분 구간의 합을 자주 구해야 할 때
  • 배열의 일부 값이 자주 갱신될 때
  • 최대/최솟값을 빠르게 구해야 할 때

이전에는 단순히 리스트 슬라이싱과 sum() 함수를 썼는데, 쿼리와 업데이트가 많아질수록 비효율적이라는 걸 알게 되었다. 이때 세그먼트 트리를 사용하면 다음과 같은 시간 복잡도를 얻을 수 있다.

  • 구간 쿼리: O(log N)
  • 값 업데이트: O(log N)

기본 아이디어

  • 세그먼트 트리는 완전 이진 트리 형태로 구성된다.
  • 리프 노드는 원래 배열의 값, 내부 노드는 해당 구간의 정보를 담는다.
  • 예를 들어 구간 합 세그먼트 트리라면, 내부 노드는 자식 노드들의 합을 저장한다.

💻 코드 구현

n = int(input())
k = 0
length = n

while length != 0:
    length //= 2
    k += 1

size = 2**k * 2
start_idx = 2**k - 1
tree = [0] * (size+1)

for i in range(start_index+1, start_index+n+1):
    tree[i] = int(input())

def create_tree(i):
    while i != 1:
        tree[i//2] += tree[i]
        i -= 1

create_tree(size-1)

def get_sum(s, e):
    result = 0
    while s <= e:
        if s % 2 == 1:
            result += tree[s]
            s += 1
        if e % 2 == 0:
            result += tree[e]
            e -= 1
        s //= 2
        e //= 2
    return result

def modify(idx, val):
    dv = val - tree[idx]
    while idx > 0:
        tree[idx] += dv
        idx //= 2

정리

  • 세그먼트 트리는 구간 쿼리와 업데이트에 효율적이다.
  • 구현이 다소 복잡하지만 한 번 잘 만들어 두면 여러 문제에 재활용 가능하다.
  • 오늘은 구간 합만 다뤘지만, 최소값, 최대값, 곱셈 등 다른 연산도 비슷한 방식으로 구현할 수 있다.

📚 참고자료

 

'Krafton Jungle > 3. TIL' 카테고리의 다른 글

[WEEK05] Ubuntu에 C 작업환경 설정하기  (0) 2025.04.10
[WEEK04] 트리 동형 사상  (0) 2025.04.09
[Week03] Trie  (0) 2025.04.02
[WEEK03] B-Tree  (0) 2025.04.02
[WEEK03] A* 알고리즘  (0) 2025.03.31