목차

장애물 경기

ps
링크acmicpc.net/…
출처BOJ
문제 번호13303
문제명장애물 경기
레벨플래티넘 3
분류

BBST

시간복잡도O(nlogn)
인풋사이즈n<=100,000
사용한 언어Python
제출기록88484KB / 2332ms
최고기록2332ms
해결날짜2022/10/13

풀이

코드

"""Solution code for "BOJ 13303. 장애물 경기".

- Problem link: https://www.acmicpc.net/problem/13303
- Solution link: http://www.teferi.net/ps/problems/boj/13303

Tags: [BBST]
"""

import sys
from teflib import fenwicktree

INF = float('inf')


def get_nums_between(ost, beg, end):
    k = ost.count_less_than(beg)
    ret = []
    for i in range(k + 1, ost.size() + 1):
        nums = ost.kth(i)
        if nums >= end:
            break
        ret.append(nums)
    return ret


def main():
    N = int(sys.stdin.readline())
    y, x = [int(x) for x in sys.stdin.readline().split()]
    obstacles = [
        [int(x) for x in sys.stdin.readline().split()] for _ in range(N)
    ]

    max_y = max(y, max(y_h for x, y_l, y_h in obstacles))
    ost = fenwicktree.OrderStatisticTree(max_y)
    ost.add(y)
    dist_by_pos = {y: 0}
    for _, y_l, y_h in sorted(obstacles):
        blocked_positions = get_nums_between(ost, y_l, y_h + 1)
        if not blocked_positions:
            continue
        dist_l = dist_h = INF
        for pos in blocked_positions:
            ost.add(pos, -1)
            dist = dist_by_pos.pop(pos)
            dist_l = min(dist_l, dist + pos - y_l)
            dist_h = min(dist_h, dist + y_h - pos)
        ost.add(y_l)
        ost.add(y_h)
        dist_by_pos[y_l] = dist_l
        dist_by_pos[y_h] = dist_h

    min_dist = min(dist_by_pos.values())
    answer = sorted(p for p, d in dist_by_pos.items() if d == min_dist)
    print(min_dist + x)
    print(len(answer), *answer)


if __name__ == '__main__':
    main()