DOJ logoDOJ
문제
최근 추가된 문제들저장한 문제
카테고리DLC대회그룹팀게시판
랭킹
문제 풀이 랭킹스트릭 랭킹DOJ Power 랭킹
현황
문제 제안로그인회원가입
DOJ logoDOJ

OI 서브태스크 채점, Elo 레이팅, Discord 인증을 갖춘 커뮤니티 온라인 저지.

문제
문제 목록카테고리
커뮤니티
대회랭킹게시판공지사항외부 대회 개최이용 안내
계정
로그인회원가입채점 현황
정책
이용약관DLC 이용 규칙개인정보 처리방침API 사용 설명서언어별 채점 환경대회 순위 보상레이팅과 퍼포먼스
© 2026 DOJ
모든 권리 보유
해설

숙제 사다리

문제로 돌아가기

해설

쿼리가 주어진 순서와 가로줄을 지나는 순서는 서로 다르다. 쿼리 순서는 각 질문에 어떤 가로줄이 존재하는지를 결정하고, 높이 순서는 존재하는 가로줄을 어떤 순서로 지나는지를 결정한다. 전체 입력을 먼저 읽고 이 두 순서를 분리해서 처리한다.

222번 쿼리의 개수를 DDD라고 하고, 이 쿼리들에 등장 순서대로 0,1,…,D−10,1,\ldots,D-10,1,…,D−1의 번호를 붙인다. 가로줄을 추가할 때 그 전에 등장한 222번 쿼리가 kkk개였다면, 이 가로줄은 번호가 kkk 이상인 질문에만 존재한다. 따라서 각 가로줄에 연결하는 세로줄 iii, 높이 hhh, 경계 kkk를 저장한다. D=0D=0D=0이면 답을 출력할 쿼리가 없으므로 이 테스트 케이스의 처리를 끝낸다.

각 질문을 자신의 출발 세로줄에 놓인 공이라고 생각하자. 세로줄 ccc마다 현재 그 줄에 있는 질문 번호의 집합 ScS_cSc​를 유지한다. 처음에는 2 x2\ x2 x로 주어진 질문의 번호를 SxS_xS에 넣는다.

모든 가로줄을 높이 hhh의 오름차순으로 정렬하여 위에서부터 처리한다. (i,h,k)(i,h,k)(i,h,k)인 가로줄에 도달하면 SiS_iSi​와 Si+1S_{i+1}에서 번호가 이상인 원소만 서로 교환한다. 번호가 보다 작은 질문에는 이 가로줄이 아직 추가되지 않았으므로 영향을 주지 않는다. 같은 높이의 가로줄은 세로줄을 공유하지 않으므로 어느 순서로 처리해도 된다.

이 교환을 빠르게 수행하기 위해 각 집합을 좌표 구간 [0,D−1][0,D-1][0,D−1]의 동적 세그먼트 트리로 저장한다. 질문 번호가 들어 있는 리프와 그 조상만 필요한 만큼 만든다. 모든 세로줄의 트리는 같은 방식으로 구간을 나누므로, 같은 구간을 나타내는 두 부분 트리를 통째로 교환할 수 있다.

두 트리에서 구간 [k,D−1][k,D-1][k,D−1]을 교환하는 연산은 다음과 같다. 현재 두 노드가 나타내는 구간을 [l,r][l,r][l,r]라고 하자.

  • r<kr<kr<k이면 교환할 원소가 없으므로 끝낸다.
  • k≤lk\leq lk≤l이면 두 노드의 참조를 통째로 교환하고 끝낸다.
  • 나머지 경우에는 l<k≤rl<k\leq rl<k≤r이다. 두 트리를 같은 중간점으로 나누고, 필요한 자식 쌍에 대해 재귀적으로 교환한다.

두 트리가 모두 비어 있으면 즉시 끝낼 수 있다. 일부만 교환해야 하는데 한쪽 노드가 없다면, 그쪽에 빈 노드를 만들어 두 자식을 관리한다. 노드의 참조를 교환할 때에는 부분 트리를 복사하지 않는다.

각 깊이에서 경계 kkk를 내부에 포함하는 구간은 최대 하나뿐이다. 나머지 구간은 아예 교환하지 않거나 부분 트리 하나를 통째로 교환한다. 따라서 한 가로줄의 처리는 O(log⁡(D+1))O(\log(D+1))O(log(D+1)) 시간에 끝나며, 새로 만드는 노드도 그만큼이다.

모든 가로줄을 처리한 뒤 각 세로줄 ccc의 트리를 순회한다. 그 트리에 질문 번호 ttt의 리프가 있다면 ans[t]=c\mathrm{ans}[t]=cans[t]=c로 기록한다. 이후 질문 번호 순서대로 답을 출력한다.

가로줄의 개수를 RRR이라 하면 D+R=QD+R=QD+R=Q이다. 초기 트리 구성에는 O(Dlog⁡(D+1))O(D\log(D+1))O(Dlog(D+1)), 가로줄 정렬에는 , 모든 교환에는 시간이 걸린다. 세로줄의 루트를 준비하고 마지막 트리 순회를 하는 비용을 포함한 전체 시간 복잡도는 이다. 초기 삽입과 각 교환에서 만드는 노드 수를 합하면 공간 복잡도도 이다.

증명

질문 번호 ttt와 가로줄 하나를 고정하자. 이 가로줄을 추가하기 전에 등장한 질문이 kkk개이면, t<kt<kt<k인 질문은 가로줄 추가 이전에, t≥kt\geq kt≥k인 질문은 그 이후에 주어졌다. 따라서 질문 tt의 사다리에 이 가로줄이 존재하는 조건은 정확히 이다.

Solution written by GPT6

x
​
Si+1​
kkk
kkk
O(Rlog⁡(R+1))O(R\log(R+1))O(Rlog(R+1))
O(Rlog⁡(D+1))O(R\log(D+1))O(Rlog(D+1))
O(N+Qlog⁡(Q+1))O(N+Q\log(Q+1))O(N+Qlog(Q+1))
O(N+Qlog⁡(Q+1))O(N+Q\log(Q+1))O(N+Qlog(Q+1))
t
t≥kt\geq kt≥k

높이순으로 가로줄을 처리하면서, 각 질문 번호는 해당 질문의 사다리에서 지금까지 처리한 높이까지 내려왔을 때의 세로줄 집합에 들어 있다는 불변식을 유지한다. 처음에는 각 질문을 자신의 출발 세로줄에 놓았으므로 성립한다.

(i,h,k)(i,h,k)(i,h,k)인 가로줄을 처리한다고 하자. t<kt<kt<k이면 질문 ttt에는 이 가로줄이 없으므로 위치가 변하지 않아야 한다. t≥kt\geq kt≥k이면 iii번 또는 i+1i+1i+1번 세로줄에 있을 때만 반대편으로 이동해야 한다. 다른 세로줄에 있으면 변하지 않는다. 두 집합에서 번호가 kkk 이상인 부분만 교환하는 연산은 바로 이 이동을 수행한다. 세그먼트 트리의 재귀는 교환 구간 안의 리프만 정확히 교환하므로 그 결과를 그대로 구현한다. 따라서 불변식이 유지된다.

같은 높이의 가로줄들은 서로 다른 세로줄 쌍을 사용하므로 연산 순서가 결과에 영향을 주지 않는다. 모든 가로줄을 처리하면 각 질문은 그 질문에 존재하는 모든 가로줄을 위에서부터 지난 상태이다. 불변식에 의해 마지막에 속한 집합의 세로줄 번호가 실제 도착점이므로 출력한 답은 모두 정확하다.