amit のソリューションを拡張すると、実際の数値を保存する代わりに、間隔とそれに関連するセットを保存することができます。
たとえば、間隔サイズ 5 を使用すると、次のようになります。
(1-5): [1,2,3,1000000]
(6-10): [2,1000000]
(11-15): [3]
(16-20): [1000000]
(1,7) の場合、間隔 (1-5) と (5-10) を考慮する必要があります (間隔のサイズを知ることで簡単に決定できます)。これらの範囲を交差させると、[2,1000000] が得られます。セットのバイナリ検索は、(1,7) が実際に両方のセットに存在することを示しています。
ただし、各セットの最小値と最大値を確認して、間隔のサイズをより適切に把握することをお勧めします。たとえば、最小値と最大値が 1 から 100 万になる場合、5 はおそらく不適切な選択です。
バイナリ検索を使用して値を確認できるように、おそらくそれを維持する必要があるため、サブセット範囲は (最小 + 最大)/N のようにする必要があります。ここで、2N はバイナリ検索する必要がある値の最大数です。各セット。たとえば、「セット 3 には 5 から 10 までの値が含まれていますか?」これは、5 (3) と 10 (11) に最も近い値を見つけることによって行われますが、この場合はそうではありません。各セットを調べて、セット内にある可能性のある間隔値をバイナリ検索する必要があります。これは、セットが 10 までしかないときに 100 を検索しないようにすることを意味します。
範囲 (最小値と最大値) を保存することもできます。ただし、問題は、番号がクラスター化されると思われるため、あまり役に立たないことです. 前述のように、間隔の設定方法を決定するのにおそらく役立つでしょう。
使用する範囲を選択するのはまだ面倒です。大きすぎると、データ構造を構築するのに長い時間がかかります (1000 * 100 万 * log(N))。小さすぎると、スペースの問題が発生し始めます。範囲の理想的なサイズは、おそらく、各範囲に関連するセットの数がほぼ等しくなるようにすると同時に、範囲の合計数が多すぎないようにすることです。
編集: 利点の 1 つは、実際にはすべての間隔を保存する必要がなく、必要なものだけを保存できることです。ただし、未使用の間隔が多すぎる場合は、間隔を増やして現在の間隔を分割して、検索が高速になるようにすることをお勧めします。これは、処理時間が大きな問題でない場合に特に当てはまります。