データ構造クラスに関する次の宿題の質問に何時間も行き詰まっています。
{1、。からn個の整数の静的セットS(つまり、Sは変更されない)が与えられます。 。 。 、u}。
O(1)時間で次のクエリに答えることができるサイズO(n log u)のデータ構造を説明します。
Empty(i, j)
-Sにiとjの間の要素がない場合にのみTRUEを返します(iとjは{1、。。。、u}の整数です)。
最初はy-fast-trieを使うことを考えました。
Y-fast-trieを使用すると、O(n) spaceおよびO(loglogu) queryを実行することで、iの後継を見つけて、それがより大きいかどうかを確認することでjより)。
しかしO(loglogu)はO(1)ではありません...
次に、配列を並べ替えて、配列にない範囲のサイズn + 1の2番目の配列を作成し、クエリで[i、j]が範囲ですが、O(nlogu)スペースを使用し、O(1)でクエリに応答できる方法はありませんでした。
私はこれを解決する方法を知りません、そして私は解決策にさえ近づいていないように感じます、どんな助けでもいいでしょう。
で構成されるデータ構造を考えます
サイズu
の配列_A[1,...,u]
_。Sにi
が存在する場合は_A[i]=1
_、それ以外の場合は_A[i]=0
_になります。この配列は、O(n)のセットS
から構築できます。
u
の累積合計を格納するサイズA
の配列_B[1,...,u]
_、つまり_B[i] = A[1]+...+A[i]
_。この配列は、すべての_B[i] = B[i-1] + A[i]
_に対して_i>1
_の関係を使用して、O(u) from A
から構築できます。
目的のブールクエリを返す関数empty(i,j)
_i==1
_の場合は_count = B[j]
_を定義し、そうでない場合は_count = B[j]-B[i-1]
_を使用します。 count
は、_[i,j]
_の範囲にあるSの個別の要素の数を与えることに注意してください。 count
を取得したら、_count==0
_を返します。明らかに、各クエリはO(1)を取ります。
編集:コメントで指摘されているように、このデータ構造のサイズはO(u)であり、制約と一致しません。しかし、それが他の人に狙いを定めるためのおおよその目標を与えることを願っています。
それは解決策ではありませんが、コメントでそれを書くことは不可能です。問題から一般的なタスクを解決するのに役立つ可能性のある、より具体的なタスクを解決する方法のアイデアがあります。
特定のタスクは、u = 1024の点を除いて同じです。また、これは最終的なソリューションではなく、(特定のタスクの)概略図です。
データ構造の作成:
次の疑似コードの画像では、単純にするために、32を除く8ビットを使用しています。
Empty(i, j) {
I = i / 32
J = j / 32
if I != J {
if P == 0: return true
if P(I) == 0: return true
if P(J) == 0: return true
} else {
if P(J=I) == 0: return true
}
return false
}