Union of Rectangles (large)

2 secs 1024 MB
Tonegawac's icon Tonegawac

平面走査によって時間計算量 O(NlogN)O(NlogN) で解くことができます。

まず、1次元の配列に対して以下の2種の操作を考えます。

  • range_add(l,r,x):range\_add(l, r, x): 区間 [l,r)[l, r) の要素のそれぞれに xx を足す。なお、この操作の後任意の要素が 00 以上であることが保証される。
  • range_union():range\_union(): 配列中の 00 より大きい要素の数を数える。

これは、要素に{区間の最小値, 区間中の最小値の数}を持つ遅延セグメントツリーを使うと実現することができます。

次に、本問題について考えます。
xx 座標を小大となるように見ていくと、以下のイベントが起こります。

  • 現在見ている xx 座標を xcurx_{cur} とする。
  • 長方形の和集合のうち、xcurx_{cur} の部分を答えに足す。 ans=ans+range_unionans = ans + range\_union
  • xcurx_{cur} がある長方形の lxlx と一致する場合、その長方形を追加する。 range_add(ly,ry,+1)range\_add(ly, ry, + 1)
  • xcurx_{cur} がある長方形の rxrx と一致する場合、その長方形を削除する。 range_add(ly,ry,1)range\_add(ly, ry, - 1)

これを全てのxx座標について行うことで解けますが、O(max(NlogN,xmaxxmin))O(max(NlogN, x_{max} - x_{min})) となるため座標のスケールが大きいと間に合いません。

そこで、range_unionrange\_union の値が変化する xx 座標のみに注目します。
range_unionrange\_union の値が変化する可能性があるのは長方形の追加、削除が行われたときのみであるため、

Δx:=x次に追加、削除が起きるタイミングxcur\varDelta x := x_{次に追加、削除が起きるタイミング} - x_{cur}

として、range_union×Δxrange\_union × \varDelta x を答えに足していくと全体で O(NlogN)O(NlogN) で解くことができます。