Official

009 - Three Point Angle(★6) Editorial by Kazu1998k


解法1 (全探索)

相異なる \(i, j, k\) 全てに対して, \(\angle P_i P_j P_k\) を求めることができれば, 最大値も求めることができる.

ここで, \(\angle P_i P_j P_k\) を求めるために, ベクトルの内積を用いる. \(P_i, P_j, P_k\) を 原点 \(O=(0,0)\) に関する位置ベクトルとみなし, ベクトル \(\boldsymbol{u}, \boldsymbol{v}\)

\[ \boldsymbol{u}=P_i-P_j, \quad \boldsymbol{v}=P_k-P_j\]

としたとき, 内積に関する式

\[\langle \boldsymbol{u}, \boldsymbol{v} \rangle=|\!|\boldsymbol{u}|\!| |\!| \boldsymbol{v}|\!| \cos \angle P_i P_j P_k\]

から,

\[ \angle P_i P_j P_k={\rm Cos}^{-1} \dfrac{\langle \boldsymbol{u}, \boldsymbol{v} \rangle}{|\!|\boldsymbol{u}|\!| |\!| \boldsymbol{v}|\!|}\]

と求めることができる. 計算量は \(O(N^3)\) になる.

解法2 (偏角ソート)

\(P_j\) を固定する. \(N-1\) 個のベクトル \(\boldsymbol{w}_{j,i}~(i \neq j)\)\(\boldsymbol{w}_{j,i}:=P_i-P_j\) とする. ここで, \(\boldsymbol{w}_{j,i}\) を偏角の昇順に並び替えた結果を \(\boldsymbol{q}_1, \dots, \boldsymbol{q}_{N-1}\) とし, \(\boldsymbol{q}_m\) の偏角を \(\theta_m~(0 \leq \theta_m < 2\pi)\) とする. ここで, \( \boldsymbol{q}_1, \dots, \boldsymbol{q}_{N-1}\)\(P_1, \dots, P_{j-1}, P_{j+1}, \dots, P_N\) の間には1対1の対応があることに注意すること.

\(\boldsymbol{q}_m\) を一つ選び, \(\boldsymbol{q}_m=P_i-P_j\) とする. ここで, \(i,j\) を固定したときに, \(\angle P_i P_j P_s\) を最大にする \(s\) の可能性があるのは, 以下で記した2つに限ることがわかる.

\(\theta_{l} \leq \theta_m \pm \pi \leq \theta_{l+1}\) となるような \(l\)\(\pm\) を適切に選ぶことにより, 必ず存在するが, このとき, 上で述べた \(s\)\(l, l+1\) の2つに限る. ただし, 添字について, \(N\)\(1\) は同一視する.

以上の工程について, \(i,j\) を固定して \(l\) 求めるために二分探索を利用して, \(O(\log N)\) で求められ, 全体で \(O(N^2 \log N)\) である. この計算量は \(N \leq 2000\) という制約下では高速である.

posted:
last update: