[백준] 18838. 가장 긴 증가하는 부분 수열 k

newbieski·2022년 6월 8일
0

백준

목록 보기
150/210

https://www.acmicpc.net/problem/18838

문제요약

  • LIS 중에서 사전순으로 K 번째를 찾기
  • 서로 다른 숫자(다행히)
  • N : 10^5

접근법

  • https://www.acmicpc.net/problem/17411 문제를 응용할 수 있음
  • 큰 흐름
    • 각 숫자로 시작하는 LIS의 길이, 경우의 수를 계산
    • 주어진 수열의 LIS의 길이가 X라고 할때
    • X의 길이를 갖는 가장 작은 숫자부터 경우의 수를 비교
      • 경우의 수 > K : 해당 숫자로 시작하는 LIS는 K번째에 들어오지 않음
      • 경우의 수 < K : 해당 숫자로 시작하는 LIS는 K번째에 들어옴
    • X-1, X-2, ... 에 대해 반복으로 수행하고, K도 업데이트 시켜줌
  • 각 숫자로 시작하는 LIS의 길이 찾기
    • lower_bound나 segment tree로 해결 가능
  • 경우의 수 계산
    • 구하고자 하는 곳의 LIS의 길이가 X일때, 구해야하는 것은 길이 : X-1, 위치 : 오른쪽, 숫자 : 커야함
    • 길이가 X-1인 것들의 (숫자, 위치)를 모아서 정렬시켜놓음
    • 길이가 X인 것들의 (숫자, 위치)를 모아서 정렬시켜놓음
    • 길이가 X인 것들을 큰 것부터 살펴보는데, X-1에서는 이보다 큰 것들을 segment tree에 업데이트함. 이후 오른쪽 것들의 합을 구함(LIS를 구간트리로 구하는 아이디어)
    • 작업이 끝나고 난 후 X-1에 사용한 것들을 대상으로만 "0"으로 segment tree에서 업데이트 => segment tree 전체를 클리어하면 시간복잡도에서 걸림
  • K 번째 찾기
    • 길이[] 배열에 시작하는 숫자를 담고 정렬
    • 이후 K 번째 수 찾기 기법 사용
profile
newbieski

0개의 댓글