2D 平面上のN (N <= 10 6 ) 点と整数 D (N <= 10 6 ) が与えられた場合、2 つの点 p1,p2 (p1 の右側にある p2) を見つけて、p1.y
でp2.y
あり、少なくとも D であり、p2.x - p1.x
最小化されます。
x 軸と y 軸の範囲は 0..10 6
これはUSACO の過去のコンテストの問題です。
ここにそれを解決するための私の試みがあります:
MAXY = N ポイント間の最大 y 軸。
p1 を知っていると仮定すると、p2 は非常に簡単に見つけることができます。p1.y+D
y 軸がMAXY から MAXY までの範囲または 0 から までの範囲にあるすべてのポイントをp1.y-D
取得し、最小の x 軸が より大きいポイントを取得しますp.x
。これは、p2 に最適な選択です。
しかし、p1 がわからないので、p1 のすべてのポイントを試す必要があるため、p2 の最適な選択を効率的に見つける必要があります。
そのためにセグメントツリーを使用しました。ツリー内のすべてのノードは、対応する範囲内のすべてのポイントを x 軸のソート順に格納します。クエリ中に、ノードがクエリ範囲内にある場合、配列でバイナリ検索を行い、p1.x
それよりも大きい最小の要素を返します。
p1 を選択するたびに、範囲 0,p1.yD と p1.y+D,MAXY を使用してツリーを 2 回クエリし、返された 2 つのポイントの中で最も良いものを取得します。
ツリーの構築は O(NlogN) 時間で実行できます。すべてのクエリには O(logN*logN) 時間がかかり、N 個のクエリを作成するため、合計所要時間は (Nlogn*logn) であり、2 秒の時間制限内で実行されない可能性があります。(10 6 *20*20)。また、使用されるメモリは O(NlogN) になり、これは約 80 mb (100000*20*4 kb) であり、制限が 64 mb であるため多すぎます。
クエリをより速く、より少ないスペースで実行するにはどうすればよいでしょうか?