세그먼트 트리(Segment Tree) 

  • 특정 구간 내 연산에 대해서 빠르게 응답하기 위해 만들어진 자료구조
    - 1,2,3,4,5라는 수들 중 2번째부터 5번째까지의 합을 구하고 싶다!
       = 배열로 구간합을 저장하고 sum[5] - sum[1]으로 구할 수 있다. -> 시간 복잡도 : O(1)

    - 만약 배열의 값이 바뀐다면?
      = 바뀔때마다 구간합을 더해서 다시 저장해야한다. -> 시간 복잡도 : O(N^2)

    - 세그먼트 트리를 사용했을 경우에는 시간 복잡도 O(NlogN)

 

  • 세그먼트 트리 만들기

 

 

 

 

구현

    • 트리 만들기
1
2
3
4
5
public static int init(int node_idx, int start, int end) {
        if(start==end) return tree[node_idx] = arr[start]; //start == end인 경우 : leaf노드

// 자식노드를 더한다 (왼쪽 노드 + 오른쪽 노드)
        return tree[node_idx] = init(node_idx*2, start, (start+end)/2+ 
init(node_idx*2+1, (start+end)/2+1, end);
}
cs

 

    • 배열 값 변경 (구간합 수정)
1
2
3
4
5
6
7
8
9
10
public static void update(int node_idx, int start, int end, int idx, long diff) {
        if(idx < start | idx> end) return;
 
        tree[node_idx]+=diff;
 
        if(start!=end) {
            update(node_idx*2,start,(start+end)/2,idx,diff);
            update(node_idx*2+1, (start+end)/2+1, end, idx, diff);
        }
}
cs

 

    • 구간합 구하기
1
2
3
4
5
6
7
8
9
public static int sum(int node_idx, int start, int end, int L, int R) {
        if(end<|| start>R) return 0;
        
        if(L<=start && end<=R) return tree[node_idx];
        
        return sum(node_idx*2, start, (start+end)/2,L,R) + 
sum(node_idx*2+1, (start+end)/2+1, end, L,R);
        
}
 
cs

 

세그먼트 트리 관련 문제

 

2042번: 구간 합 구하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 합을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄

www.acmicpc.net

 

 

 

'정리 > 자료구조+알고리즘' 카테고리의 다른 글

투 포인터(Two Pointer)  (0) 2021.08.26
이진 탐색 (Binary Search) 알고리즘  (0) 2021.07.05
위상정렬  (0) 2021.06.18
비트마스크 (BitMask)  (0) 2021.04.21
최소신장트리(MST) 알고리즘  (0) 2021.03.26

+ Recent posts