DOJ logoDOJ
题目
最近添加的题目收藏的题目
分类DLC比赛小组团队讨论区
排名
解题数量排行榜连续解题排名DOJ Power 排行榜
评测状态
征题登录注册
DOJ logoDOJ

支持 OI 子任务计分、Elo 等级分和 Discord 认证的社区在线评测系统。

题目
题目列表分类
社区
比赛排名讨论区公告举办外部比赛指南
账号
登录注册评测状态
政策
服务条款DLC 使用规则隐私政策API 文档语言运行环境比赛排名奖励评级与表现
© 2026 DOJ
保留所有权利
题解

Homework Ladder

返回题目

题解

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

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 이상인 부분만 교환하는 연산은 바로 이 이동을 수행한다. 세그먼트 트리의 재귀는 교환 구간 안의 리프만 정확히 교환하므로 그 결과를 그대로 구현한다. 따라서 불변식이 유지된다.

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