2020年1月29日水曜日

JOI2007 春合宿 - lines

同一の直線は最初に除いておく。以下、NN本の直線は相異なるとする。

平面走査的に考えてみる。つまり、十分に大きな正数aaについてxx軸に平行な直線L:y=aL: y=aを用意して、この直線を下に移動しながら領域の数を数える。y=ay=aと平行な直線はないとしてよい。[1] 最初に直線LLNN本の直線と交わっていて、これらに区切られたN+1N+1個の領域にまたがっている。LLを下に移動していくとき、LLが新たな領域に出会うのは直線の交点に一致した瞬間である。このとき、交点を通る直線が2本なら領域が1つ増え、3本なら2つ増え、一般にkk本の直線の交点ではk1k-1本増えている。

以上の観察より、単にl1l_1から順に直線を追加していき、新しい直線を追加するたびにこれまで追加した各直線と交わる点を(平行でなければ)検出し、同じ交点を検出した回数を数えていけばよい。

NN本の直線を処理したあと、ある交点PPをちょうど22本の直線が通ったなら、PP11回数えられ、33本なら1+2=31+2 = 3回数えられる。一般に、k+1k+1本の直線の交点は1+2+...+k=k(k+1)/21+2+...+k = k(k+1)/2回数えられていて、そこで増えた領域はkk個になっている。二次方程式を解くと、点PPvv回数えられたならそこで増えた領域は(1+1+8v)/2(-1+\sqrt{1+8v})/2個である。計算量はO(N2){O}(N^2)


  1. あったら、全体を適当に回転させたものを考えればよい。 ↩︎