[알고리즘] Prefix sum와 Segment Tree의 원리

안우진·2026년 4월 24일

알고리즘

목록 보기
4/4

1. 대수 구조의 정의

Monoid (단양군)

집합 MM과 이항 연산 \ast의 쌍 (M,)(M, \ast)이 다음 두 조건을 만족하면 Monoid라고 한다.
1. 결합 법칙 (Associativity): a,b,cM,(ab)c=a(bc)\forall a, b, c \in M, (a \ast b) \ast c = a \ast (b \ast c)
2. 항등원 존재 (Identity): eM,aM,ea=ae=a\exists e \in M, \forall a \in M, e \ast a = a \ast e = a

Group (군)

Monoid (M,)(M, \ast)가 다음 조건을 추가로 만족하면 Group이라고 한다.
3. 역원 존재 (Inverse): aM,a1M,aa1=a1a=e\forall a \in M, \exists a^{-1} \in M, a \ast a^{-1} = a^{-1} \ast a = e
예로, <Z,+><\Z,+>, <Zn,><\Z_n^*,*> 는 Group 이다.


2. Prefix Sum의 정의와 Group에 의한 O(1)O(1) 증명

정의

수열 A= <a1,a2,,an> GA=\ <a_1, a_2, \dots, a_n>\ \subset G에 대하여 Prefix Sum SS는 다음과 같이 재귀적으로 정의된다.

s0=e,si=si1ais_0 = e, \quad s_i = s_{i-1} \ast a_i

구간 쿼리 증명 (Group)

구간 [l,r][l, r]의 연산 결과 Pl,r=alal+1arP_{l,r} = a_l \ast a_{l+1} \ast \dots \ast a_r이라 할 때, sr=sl1Pl,rs_r = s_{l-1} \ast P_{l,r}이 성립한다.
(G,)(G, \ast)Group이면 역원 sl11s_{l-1}^{-1}이 존재하므로,

sl11sr=sl11(sl1Pl,r)s_{l-1}^{-1} \ast s_r = s_{l-1}^{-1} \ast (s_{l-1} \ast P_{l,r})

결합 법칙에 의해

sl11sr=(sl11sl1)Pl,r=ePl,r=Pl,rs_{l-1}^{-1} \ast s_r = (s_{l-1}^{-1} \ast s_{l-1}) \ast P_{l,r} = e \ast P_{l,r} = P_{l,r}

따라서 Pl,r=sl11srP_{l,r} = s_{l-1}^{-1} \ast s_rO(1)O(1) 계산이 가능하다.

예시

수열 A= <a1,a2,,an> ZnA =\ <a_1, a_2, \dots, a_n>\ \in \mathbb{Z}^n 와 쿼리 [l,r][l, r] 에 대해 i=lrai\sum_{i=l}^{r}a_i 를 구한다고 하자.
<Z,+><\Z,+>는 Group이므로 Prefix Sum SS를 정의할 수 있다.
++ 연산자에서 정수 aa의 역원은 a-a이므로 sl11=sl1s_{l-1}^{-1} = -s_{l-1} 이다.

스위핑, 차분배열 또한 역원을 사용하므로 Prefix Sum과 비슷하다.


3. Segment Tree와 Monoid의 수학적 증명

Segment Tree는 구간 [l,r][l, r]을 서로소인 부분 구간들의 합집합으로 분할한다.

Group이 아닌 Monoid로 충분한 이유

임의의 구간 [L,R][L, R]이 Segment Tree의 노드 집합 {v1,v2,,vk}\{v_1, v_2, \dots, v_k\}에 의해 관리되는 부분 구간들의 합집합으로 분할된다고 가정한다.

[L,R]=[i1,j1][i2,j2][ik,jk][L, R] = [i_1, j_1] \cup [i_2, j_2] \cup \dots \cup [i_k, j_k]

이때 각 노드 vmv_m에 저장된 값을 Val(vm)Val(v_m)이라 하면, 전체 구간의 값은 다음과 같다.

Val(v1)Val(v2)Val(vk)Val(v_1) \ast Val(v_2) \ast \dots \ast Val(v_k)
  1. 결합 법칙의 필연성:
    Segment Tree는 완전 이진 트리 구조로 연산을 수행하므로, 계산 순서가 ((v1v2)v3)((v_1 \ast v_2) \ast v_3) \dots와 같이 고정되지 않고 트리의 형태에 따라 임의의 괄호 배치가 발생한다.
    vi,vj,vk\forall v_i, v_j, v_k, (vivj)vk=vi(vjvk)(v_i \ast v_j) \ast v_k = v_i \ast (v_j \ast v_k) 가 만족되어야만 트리의 분할 방식에 관계없이 동일한 값을 보장한다.

  2. 역원의 불필요성:
    Segment Tree는 srs_r에서 sl1s_{l-1}을 제거하는 방식이 아니라, 필요한 구간들만을 합성하여 값을 구축한다. 따라서 xx1=ex \ast x^{-1} = e와 같은 역원 연산이 논리적으로 필요하지 않다.

  3. 항등원의 역할:
    쿼리 범위 밖의 노드를 처리할 때 v=vev = v \ast e 연산을 수행함으로써 알고리즘의 일관성을 유지한다.

2개의 댓글

comment-user-thumbnail
6일 전

좋은 글이네용가리치킨

1개의 답글