D - Spacecraft 解説
by
noya2
宇宙船、つまり原点を中心とする半径 \(R\) の球を \(B\) とします。 \(P_i\) を端点に持つ半直線であって \(B\) に接するものによって囲まれた領域を考えると、その形状は \(P_i\) を頂点とする円錐になっています。この円錐を頂点が原点 \(O\) になるように平行移動させたものを \(\lambda_i\) とします。また、平行移動する前の円錐を、その円錐と球面の交面で切って \(P_i\) を含まない側を残した領域を \(\Lambda_i\) とすれば、これは \(i\) 番目の星を見ることができない領域に一致しています。
ただし、図形は \(\mathbb{R}^3\) 上の点の集合として考えます。また \(\lambda_i,\Lambda_i\) はその境界を含みます。
本問題は、原点を中心とする半径 \(1\) の球面 を \(S\) としたとき、 \(S\setminus\bigcup_i\lambda_i\) がいくつの領域に分かれているかを求める問題です。
この帰着は自明ではないので、証明を記します。
証明
三次元上の点と三次元ベクトルを同一視します。
点 \(p\) が素敵な点であるとき、 \(1\) 以上の任意の実数 \(k\) に対して点 \(kp\) は素敵な点です(すなわち、原点から遠ざかる方向に移動した点も素敵な点です)。そこで、原点を除く任意の点 \(p\) の、原点から見た方向 \(p/|p|\) に注目します。このとき、方向 \(d\ (|d|=1)\) に対して次の \(2\) つは同値です。
- 方向 \(d\) を持つ素敵な点が存在する
- \(d\in (S\setminus\bigcup_i\lambda_i)\)
下の条件は \(|d|=1\) より \(d\notin \bigcup_i\lambda_i\) つまり \(\forall i, d\notin\lambda_i\) と言い換えられます。 \(\lambda_i\) は \(i\) 番目の星を見ることができない領域に完全に含まれているため、上の条件 \(\implies\) 下の条件は明らかです。 \(\impliedby\) も \(\lambda_i\) と \(\Lambda_i\) の「側面」が平行であることから、十分大きな実数 \(F(d)\) を取ることで \(\forall i,F(d)d\notin \Lambda_i\) を満たすことができるため、成り立ちます。
帰着の正当性の確認の前に、少し記法を追加します。球面 \(S\) 上で \(\bigcup_i\lambda_i\) に含まれない点を「球面 \(S\) において素敵な点である」ということにします。また、球面 \(S\) において素敵な点である点の集合を \(L_S\) とします。さらに、 \(p_1,p_2\in L_S\) が同じ連結成分に属するとはすなわち \(p_1,p_2\) を通る \(L_S\) 上の曲線が存在することであり、このことを \(p_1\sim_S p_2\) と表します。
帰着の正当性を確認しましょう。素敵な点 \(p_1,p_2\) に対して \(p_1\sim p_2\) であることと、 \(p_1/|p_1|\sim_S p_2/|p_2|\) が同値であることを示せば良いです。
まずは \(p_1\sim p_2\implies p_1/|p_1|\sim_S p_2/|p_2|\) を示します。 \(p_1,p_2\) を結ぶ \(L\) 上の曲線をひとつとり、曲線上の点を \(f:L\to L_S, f(p)=p/|p|\) によって写せば、 \(f\) は明らかに連続なので \(L_S\) 上の曲線になり、ただちに \(p_1/|p_1|\sim_S p_2/|p_2|\) が導かれます。
次に \(p_1\sim p_2\impliedby p_1/|p_1|\sim_S p_2/|p_2|\) を示します。 \(p_1/|p_1|,p_2/|p_2|\) を結ぶ \(L_S\) 上の曲線をひとつとり、曲線上の点を \(g:L_S\to L, g(d)=F(d)d\) によって写せば、 \(g\) もまた明らかに連続なので \(L\) 上の(有限長の)曲線になり、ただちに \(p_1\sim p_2\) が導かれます。
\(S\) と \(\lambda_i\) の交線は円になります。上の図は、サンプルの 1 つめのテストケースにおいてそれらの円と \(S\) を表示したものです。
次に帰着後の問題を注意深く観察します。球面上にいくつかの円が描かれているとき、そのすべての外側にある球面上の領域がいくつあるか、という問題になっています。ここで、球面上に描かれたそれらの円は、それぞれある平面上に乗っていることに注目し、次のように言い換えます。
球面 \(S\) をいくつかの平面で切断し、平面に対して原点と同じ側の部分だけ残したとき、いくつの領域に分かれるか。
ここで \(S\) と \(\lambda_i\) の交面との境界となる円を含む平面を \(\sigma _i\) とし、 \(\sigma _i\) に対して原点側の半空間を \(H_i\) とします。そして \(i=1,2,\dots ,N\) に対する半空間 \(H_i\) の積(halfspace intersection)としての凸包 \(C\) を考えます。このとき \(S\cap C\) がいくつの領域に分かれているかを求めたいです。
必要ならば \(S\) を完全に含むような半空間をさらにいくつか追加することで \(C\) は有限の領域に収まっているとします。 \(S\cap C\) は特に \(C\) の内側の領域で、逆に言えば球面の外側に \(C\) の一部が存在することになります。このことに注目して、凸包によって切り取られた球ではなくて、逆に球によって切り取られた凸包に焦点を当ててみましょう。つまり \(C\) のうち原点からの距離が \(1\) より大きな部分 ( \(=C^\prime\) ) がいくつの領域に分かれているかを求めることができれば、それが元の問題の答えになっています。
\(C\) 上の点であって原点からの距離が極大となる点は \(C\) の頂点のみであることから、異なる \(2\) 頂点が同じ領域にあるためには \(C^\prime\) 上の \(C\) の辺を辿って行き来可能であることが必要十分です。以上の考察から次の解法が得られます。
- \(i=1,2,\dots ,N\) に対して平面 \(\sigma_i\) を計算し、それにより定まる半空間 \(H_i\) たちの積としての凸包 \(C\) を計算する。
- 必要ならば \(S\) を完全に含む半空間をいくつか追加して \(C\) を有限にする。
- \(C\) のうち原点からの距離が \(1\) より大きな点および辺からなるグラフの連結成分の個数を答える。
半空間の積としての凸包を計算するアルゴリズムはいくつか知られていますが、例えば平面を \(N\) 通り全て調べ、その平面上での半平面の積(halfplane intersection)を偏角ソートを用いて \(O(N\log N)\) 時間で計算する方法によって、 \(1\) ケースあたり \(O(N^2\log N)\) の時間計算量で凸包を計算することができます。辺および頂点の個数は \(O(N)\) であることから、連結成分の個数を求めるパートは UnionFind などを用いればボトルネックになることはありません。
投稿日時:
最終更新:
