You will be fine

<알고리즘> 4. 세그먼트트리 JAVA

by BFine
반응형

가. 세그먼트 트리 

 a. 무엇인가

  -   어떤 배열의 구간합을 트리형태로 저장

 

 b. 특징

  -  배열로 구간합을 저장하고 (S[i]= S[i-1]+A[i]) 원하는 구간을 (S[R] - S[L-1])의 형태로 구현이 가능[O(1)] 

  -  하지만 배열의 값이 바뀌는 경우 바뀔때마다 구간합을 더해서 저장해야한다 O(N*변경)

  -  세그먼트 트리는 이를 O(logN)으로 만들어 줄 수 있다.

 

나. 구현

 a. DFS 및 이분탐색의 활용

  -  node는 1번부터 시작하며 node*2가 왼쪽 자식노드 node*2+1이 오른쪽자식 노드가 된다.

  -  트리의 구성은 이분탐색으로 쭉쭉 내려가면서 start랑 end가 같아질때 해당 노드번호에 요소를 저장한다.

  -  리프에 저장이 끝나면 위로 돌아와서 해당구간을 더한 값을 저장해준다.

public class 세그먼트트리 {

    public static void main(String[] args){

        new 세그먼트트리().start();
    }
    int[] arr;
    int[] tree;

    public void start(){
        arr = new int[]{1, 2, 3, 4, 5, 6};
        tree = new int[arr.length*3];

        트리만들기(1,0,arr.length-1);
        System.out.println(구간합찾기(1,0, arr.length-1, 1,3));
        int temp = arr[2];
        arr[2] = 2;
        int diff = temp - arr[2];
        변경된요소_업데이트(1,0,arr.length-1,2,diff);
        System.out.println(구간합찾기(1,0, arr.length-1, 1,3));

    }

    public int 트리만들기(int node,int start,int end){
        if(start == end){
            return tree[node] = arr[start];
        }else {
            // 왼쪽 단말과 오르쪽 단말을 더한다 (구간합)
            int mid = (start+end)/2;
            return tree[node] = 트리만들기(node*2,start,(start+end)/2)
                + 트리만들기(node*2+1,(start+end)/2+1,end);
        }
    }

    public int 구간합찾기(int node,int start,int end,int L,int R){

        if(end < L || R < start) return 0; // 찾는범위가 아닌경우

        if(L <= start && end <=R){
            return tree[node];
        }else {
            int mid = (start+end)/2;
            return 구간합찾기(node*2,start,mid,L,R)
                    +구간합찾기(node*2+1,mid+1,end,L,R);
        }
    }

    public void 변경된요소_업데이트(int node, int start, int end, int idx, int diff){
           if(idx < start || idx > end) return;
           tree[node] = tree[node] + diff;
           int mid = (start+end)/2;
           if(start != end){
               // 리프노트는 이미 변경된 상태이므로 변경할 필요없음!

               변경된요소_업데이트(node*2,start,mid,idx,diff);
               변경된요소_업데이트(node*2+1,mid+1,end,idx,diff);
           }
    }
}

 

 

출처 : www.acmicpc.net/blog/view/9

 

세그먼트 트리 (Segment Tree)

문제 배열 A가 있고, 여기서 다음과 같은 두 연산을 수행해야하는 문제를 생각해봅시다. 구간 l, r (l ≤ r)이 주어졌을 때, A[l] + A[l+1] + ... + A[r-1] + A[r]을 구해서 출력하기 i번째 수를 v로 바꾸기. A[i

www.acmicpc.net

 

반응형

'알고리즘 > 이론' 카테고리의 다른 글

<알고리즘> 3. LRU 캐시 JAVA  (0) 2021.04.19
<알고리즘> 2. 위상정렬 JAVA  (0) 2021.04.17
<알고리즘> 1. 다익스트라 JAVA  (0) 2021.04.17

블로그의 정보

57개월 BackEnd

BFine

활동하기