かんプリンの学習記録

勉強したことについてメモしています. 主に競技プログラミングの問題の解説やってます.

ABC256 D - Union of Interval

問題はこちら

問題概要

{N}個の半開区間{[L_i,R_i)}の和集合を求めよ.

  • {1\leq N\leq 2×10^5}
  • {1\leq L_i < R_i\leq 2×10^5}

解説

以下のように半開区間の集合に新たに半開区間を追加することを考えます.

このような追加を高速に行うことができれば解くことができそうです.
既に集合に含まれる区間と追加する区間が重なっていなければそのまま追加すればいいだけですが,重なっている場合はうまく処理する必要があります.

具体的には,追加する区間{S},集合内の区間{L}の昇順に並べたときの{i}番目の区間{S_i}としたとき,集合内の{S}と重なる区間のうち一番左の区間{S_x},一番右の区間{S_y}であれば,{S_i(x\leq i\leq y)}を削除します.その後,{L'}を「{S_x}{L}{S}{L}の小さい方」,{R'}を「{S_y}{R}{S}{R}の大きい方」としたときの{[L',R')}を集合に追加すれば区間の和集合を求めることができます.

{S_x,S_y}を高速に求められれば良いですが,これはstd::setなどのlower_boundを用いると可能になります.くわしくは実装を見てください.

提出プログラム

https://atcoder.jp/contests/abc256/submissions/32647023

感想

難しい問題の部分問題としてよく出てくる問題です.