반응형
문제링크
https://www.acmicpc.net/problem/13537
문제 총평
- 머지 소트 트리를 공부한다면 아주 쉽게 풀 수 있다.
문제 접근방식
- 이번 문제는 아무런 문제를 고른 것이 아닌 세그트리를 공부 후, 머지 소트 트리라는 것이 있어서 공부를 하고 나서 풀었습니다.
- 다른 요소가 중요하다기 보단 머지 소트 트리 연습 문제같은 느낌이니 머지 소트 트리를 모른다면 학습 후 문제를 푸시는 것을 추천드립니다.
- 또한 기존에는 sys를 잘 쓰진 않지만 이 문제에서는 sys로 입력을 받지 않으면 시간 초과가 뜨기 때문에 사용하였습니다.

정답코드
import bisect, math,sys
input = sys.stdin.readline
n = int(input())
arr = list(map(int,input().split()))
size = math.ceil(math.log2(n))+1
tree = [[] for _ in range(1<<size)]
def merge(left,right):
tem = []
i = j = 0
l = len(left)
r = len(right)
while 1:
if i == l:
for k in range(j,r):
tem.append(right[k])
break
if j == r:
for k in range(i,l):
tem.append(left[k])
break
if left[i] < right[j]:
tem.append(left[i])
i += 1
else:
tem.append(right[j])
j += 1
return tem
def init(node,start,end):
if start == end:
tree[node].append(arr[start-1])
return
mid = start + end >> 1
init(node<<1, start, mid)
init(node<<1|1, mid+1, end)
tree[node] = merge(tree[node<<1],tree[node<<1|1])
def query(node,s,e,l,r,k):
if e<l or s>r: return 0
if s >= l and e <= r:
return len(tree[node]) - bisect.bisect_right(tree[node],k)
mid = s + e >> 1
return query(node<<1,s,mid,l,r,k) + query(node<<1|1,mid+1,e,l,r,k)
init(1,0,n)
for _ in range(int(input())):
a,b,c = map(int,input().split())
print(query(1,0,n,a,b,c))
- 먼저 머지 소트 트리는 세그먼트 트리와 유사하게 만들어 집니다. 구간을 나눠서 값들을 저장합니다.
- 그런데 세그먼트 트리와 다르게 어떤 노드가 특정 arr의 값이 아니라면 (start==end 가 아닌경우) 에는 그 하위 범위의 노드들을 머지 소트를 진행하여 만든 꼴이 됩니다.
- 이는 merge 함수를 보면 되는데 이 함수는 다른 것이 아니라 여러분이 아는 머지 소트와 같은 코드입니다.
- 이렇게 머지 소트를 이용해서 구간 안의 값들이 정렬 된 상태를 만들어 냅니다.
- 그 이후에는 query 함수를 짜는데 특정 구간에서 k보다 큰 값을 찾기 위해서는 이분 탐색을 통해 k 보다 크면서 가장 작은 값의 index를 찾고 전체 길이에서 그 인섹스를 빼주면 됩니다.
- 6 이 가능한 이유는 이미 머지 소트로 노드의 구간을 정렬해 놓았기 때문에 가능하고 직접 이분탐색을 할 수 있지만 저는 python의 bisect를 사용하였습니다.
- 이렇게 구한 값을 더해 출력하면 됩니다.
문제 풀이 후 생각
- 가장 먼저 든 생각은 알고리즘 세상에서는 참 자료구조가 많고 배울 것들이 많다는 것입니다.
- 개인적으로는 플레티넘 3 이라는 난이도는 자료구조가 어려워서 이겟지만 알고보면 참 쉬운 문제라는게 느껴집니다.
- 앞으로도 이런 새로운 자료 구조들을 소개 하고자 하니 많은 관심 부탁드립니다.
모르는게 있다면 댓글 남겨 주시면 바로 답해드리겟습니다 ^^
반응형
'알고리즘' 카테고리의 다른 글
| 백준 1313번 : 합성소수 (Python) (1) | 2024.01.13 |
|---|---|
| 백준 30505: SASA 마니또 (Python) (1) | 2024.01.10 |
| 백준 2746: 좋은 배열 만들기 (Python) (0) | 2023.12.01 |
| 백준 29793: 라라와 용맥 변환 (Python) (0) | 2023.09.15 |
| [백준] 20442 ㅋㅋ루ㅋㅋ - 투 포인터 (Python) (2) | 2023.08.06 |