본문 바로가기

알고리즘/Baekjoon

(196)
구간 트리. [1168] [1. 문제 설명] 1 부터 N 까지 나열 된 원이 있을 때, 순서대로 K 번째 값을 제거 했을 때 제거되는 순서를 출력한다. [2. 풀이 접근] 기본적인 전략은 아래 문제와 동일하다. https://testkernelv2.tistory.com/412 간단히 다시 정리하면 구간에 속한 원소의 개수를 알 수 있으므로, logN 시간복잡도로 남아 있는 수열에서 k 번째 숫자를 찾는 것이다. 여기서 문제는 수열이 원형 형태라는 것이다. 예제 입력을 토대로 동작 방식을 살펴보면, (N=7, K=3) ▼ [1][2][3][4][5][6][7] ▼ [1][2][4][5][6][7] # 이전 위치를 기준으로 3번째 원소 ▼ [1][2][4][5][7] # [1][2][4][5][6][7][1][2][4][5][7] ..
구간 트리. [12899] [1. 문제 설명] 아래 쿼리를 수행하는 프로그램을 작성한다. A. 수열 S 에 자연수 X 를 추가한다. (append) B. 수열 S 에 포함된 숫자 중 X 번째로 작은 수를 출력하고, 수열에서 제거한다. [2. 풀이 접근] 간단한 풀이를 생각해보면, 트립(treap) 의 적용을 생각해 볼 수 있다. 트립을 통해 원소의 삽입과 삭제를 logN 에 할 수 있다. 또한 K번째 원소도 쉽게 찾을 수 있다. 그러나 구현이 살짝 까다로울 수 있으니, 나중에 다시 정리해보도록 하고, 구간 트리를 사용하여 풀이를 해볼 수 있다. 자연수 X 의 범위는 1 이상 2,000,000 이하이므로, 구간을 [1, 2,000,000] 을 하는 구간 트리를 생각 해 볼 수 있다. 각 노드가 저장하는 값은 구간이 포함하는 원소의 ..
구간 트리. [16975] [1. 문제 설명] 길이가 N 인 수열이 있을 때, 아래 쿼리를 수행하는 프로그램을 작성 구간 [i, j] 내 모든 값에 K 를 더한다. A[x] 를 출력한다. [2. 풀이 접근] update 횟수가 최대 N 번이고 그 때마다 각 구간의 길이는 최대 N 일 수 있으므로, 단순하게 푼다면 N3 구간트리에서 단일 index 만 업데이트 한다면 N2logN 이 걸린다. 이 문제를 푸는 방법에는 Lazy Propagation, 팬윅트리(구간 트리의 다른 버전) 등이 있다고 하는데 위 방법을 사용하지 않고 풀 수 있다. 최초 구간트리 초기화 시, 구간 트리의 단말노드에만 값을 부여하고, 단말이 아닌 노드는 0을 초기화 한다. # 아래 그림에서 구간의 길이가 1인 곳에만 배열에 설정 된 값을 부여하는 것이다. 일반..
구간 트리. [9345] [1. 문제 설명] ... [2. 풀이 접근] 1차 풀이 (실패) 구간의 합을 구하여 같은지 확인 한다. => [1, 5] 구간에 1~5 DVD 가 존재 할 경우 [1, 5] 구간의 부분 합은 1+2+3+4+5=15 가 되어야 한다. 반례) => [2, 4] 구간이 1,3,5 로 이루어진 경우 2+3+4 == 1+3+5 == 9 => 둘다 같은 값이나, 2, 3, 4 가 있어야 하나 1, 3, 5 가 있으므로 대여 조건을 만족하지 않는다. 올바른 풀이 구간의 최대, 최소를 모두 갖고 있는 경우 성공. [2, 4] 구간은 2,3,4 가 존재해야 한다. [2, 4] 구간의 최소, 최대는 2, 4 인 것이 자명하다. 시리즈는 1씩 증가하므로, [2, 4] 구간이 2 와 4 만 존재 할 수 는 없다. [3. 코..
구간 트리. [1517] [1. 문제 설명] 1 1 2 3 5 정렬 된 상태 3 2 1 5 1 최초 상태 2 3 1 5 1 3, 2 swap 2 1 3 5 1 3, 1 swap 2 1 3 1 5 5, 1 swap 1 2 3 1 5 2, 1 swap 1 2 1 3 5 3, 1 swap 1 1 2 3 5 2, 1 swap 3 이 3번의 swap 을 유도하고, 5 가 1번의 swap 2 가 2번의 swap 총 6번의 swap 이 발생하였다. [2. 풀이 접근] 이해가 된 부분 까지만 정리 하도록 swap 의 주체는 인접한 두 값 중 큰 값 이다. 예를들어, 3 과 2 의 swap 이 발생 했을 때, 3 입장에서 한번 swap, 2 입장에서 한번 swap, 총 2번의 swap 이 발생과 같은 중복 처리는 있어선 안된다. 3 이 2 를 ..
구간 트리. [2357] [1. 문제 설명] [2. 풀이 접근] 배열 내 임의의 구간에 대해서 최대, 최소를 구한다. [3. 코드]
구간 트리. [11505] [1. 문제 설명] 값이 변할 수 있는 수열에서 입력으로 주어지는 구간의 곱을 구한다. 값이 매우 클 수 있으니, 1e9+7 로 나눈 값을 출력한다. [2. 풀이 접근] 구간트리로 접근한다. 구간트리를 나타내는 배열을 최초 초기화 할 때 0 이 아닌 1로 초기화 한다. 구간에 대한 곱을 직접적으로 구한는 query 함수에서 구간이 노드가 나타내는 구간을 벗어난 경우 1 을 반환할 수 있도록 한다. [3. 코드]
구간 트리. [2042] [1. 문제 설명] N 개의 수가 주어진다. 특정 위치의 값의 변경이 M 번 발생한다. 특정 구간의 합을 K 번 해야 한다. => 수열의 값이 변할 수 있을 때, 특정 구간의 합을 계산한다. [2. 풀이 접근] 먼저 생각해 볼 수 있는 것은 먼저 부분합을 구한 후 사용하는 것 이지만, 중간의 수열 내 값이 변할 수 있기 때문에, 적절한 접근은 아니다. 두번째는 이차원 배열을 이용하는 것이지만, N 이 최대 1,000,000 이므로 메모리가 초과할 것이다. 여기서 구간 트리(혹은 Segment tree) 라는 것을 사용 해 볼 수 있다. 구간 트리는 저장된 자료들을 적절히 전처리하여 이후 쿼리를 빠르게 대응 할 수 있도록 한다. 구간 트리의 기본적인 아이디어는 주어진 배열의 구간들을 표현하는 이진 트리를 ..
최소 공통 조상. [13511] [1. 문제 설명] N 개의 정점으로 이루어진 트리가 주어졌을 때, 임의의 경로에 대해서 A. 경로의 비용을 출력 B. u->v 로 가는 경로에서 k 번째 정점을 출력 하도록 한다. [2. 풀이 접근] 경로의 비용을 sparse table 의 형태로 저장 할 수 있으며, u->v 의 LCA 를 찾는 과정에서 u->v 경로의 비용을 찾을 수 있다. 참조=> https://testkernelv2.tistory.com/398 경로의 k 번째 정점을 찾는 부분이 살짝 까다로웠다. 일단 LCA 를 찾는 것이 먼저이다. u -> LCA v -> LCA 간 높이 차이를 이용하여 k 가 어디에 있을 지 추정 할 수 있기 때문이다. 처음에 생각한 방법은 오답이었다. u 와 LCA 간 높이차이를 계산 = height1 v..
최소 공통 조상. [3176] [1. 문제 설명] N 개의 정점과 N-1 개의 edge 로 이루어진 네트워크가 존재 모든 정점 쌍에는 두 정점을 연결하는 유일한 경로가 존재 edge 의 거리가 주어짐 K 개의 정점 쌍이 주어질 때, 두 정점을 연결하는 경로 에서 가장 짧은 edge 의 길이와 가장 긴 edge 의 길이를 출력한다. [2. 풀이 접근] 먼저 주어지는 그래프는 Tree 라는 것을 알 수 있다. N 개의 정점과 N-1 개의 edge 가 존재 임의의 두 정점을 연결하는 경로가 유일함 여기서 두 정점을 연결하는 경로는 두 정점의 최소 공통 조상까지 연결되어 있다. B 에서 A 를 잇는 경로는 B 에서 출발하여 위로 계속 올라가다가 최소 공통 조상(LCA) U 에서 다시 아래로 내려가는 경로라는 것을 알 수 있다. 즉, B 에서..