새소식

PS/백준

[백준/12899] 데이터 구조 (Python)

  • -

Problem : https://www.acmicpc.net/problem/12899

 

12899번: 데이터 구조

첫째 줄에 사전에 있는 쿼리의 수 N 이 주어집니다. (1 ≤ N ≤ 2,000,000) 둘째 줄부터 N개의 줄에 걸쳐 각 쿼리를 나타내는 2개의 정수 T X가 주어집니다. T가 1이라면 S에 추가할 X가 주어지는 것입니

www.acmicpc.net

 

Difficulty : Platinum 4

 

Status : Solved(pypy)

 

Time : 00:09:45

 


 

문제 설명

 

더보기

 

자연수를 저장하는 데이터베이스 S에 대해 다음의 쿼리를 처리합시다.

유형 1 : S에 자연수 X를 추가한다.

유형 2 : S에 포함된 숫자 중 X번째로 작은 수를 응답하고 그 수를 삭제한다.

 

 

입력 및 출력

 

더보기

입력

 

첫째 줄에 사전에 있는 쿼리의 수 N 이 주어집니다. (1 ≤ N ≤ 2,000,000)

둘째 줄부터 N개의 줄에 걸쳐 각 쿼리를 나타내는 2개의 정수 T X가 주어집니다.

T가 1이라면 S에 추가할 X가 주어지는 것입니다. (1 ≤ X ≤ 2,000,000)

T가 2라면 X는 S에서 삭제해야 할 몇 번째로 작은 수인지를 나타냅니다. S에 최소 X개의 원소가 있음이 보장됩니다.

 

출력

 

유형 2의 쿼리 개수만큼의 줄에 각 쿼리에 대한 답을 출력합니다.

 

입력 예시

 

5
1 11
1 29
1 89
2 2
2 2

 

출력 예시

 

29
89

 

 


 

풀이

 

카운팅 세그먼트트리를 생성하자. X의 최댓값이 2백만이므로, 2백만까지를 수용할 수 있는 세그먼트 트리를 생성한다.

 

  • update는 일반적인 세그먼트 트리와 동일하다.
  • search의 경우 몇번째 수인지 lower bound를 찾는 경우로 바꾸어 생각할 수 있다.
  • 파이썬은 느린 언어. 다시 명심하자. 전부 비재귀 형식으로 구현해 볼 수 있겠다.

 

풀이 코드

import sys
input = sys.stdin.readline
MAX = 2000000
tree = [0]*(4*MAX+4)

def update(target) :
  start, end, idx = 0, MAX, 1
  while start < end :
    mid = (start + end) // 2
    tree[idx] += 1
    if target <= mid :
      idx = idx*2
      end = mid
    else :
      idx = idx*2 + 1
      start = mid + 1
  tree[idx] += 1

def search(target) :
  start, end, idx = 0, MAX, 1
  while start < end :
    mid = (start + end) // 2
    tree[idx] -= 1
    if target <= tree[idx*2] :
      idx = idx*2
      end = mid
    else :
      target -= tree[idx*2]
      idx = idx*2 + 1
      start = mid + 1
  tree[idx] -= 1
  return end

N = int(input())
for _ in range(N) :
  t, x = map(int, input().split())
  if t == 1 :
    update(x)
  else :
    print(search(x))

풀이 완료!

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.