リンクした論文をざっと読んだ。その論文で与えられた考えに基づいて、各操作にバインドされた時間を取得する単純なデータ構造を次に示します。O (ログんログログん)
あなたはあなたの質問であなたはこれをスピードアップするためにバランスのとれた拡張ツリーを使うことができると述べました。特に、バイナリツリーがあり、各ノードに左のサブツリーのパリティを追加する場合は、それぞれ時間で更新と検索を実行できます。これは高速ですが、十分な速度ではありません。O (ログn )
ここで、以下のアイデアの一般化を検討してください。二分木を使用する代わりに、分岐因数多元木を使用するとします。各ノードの各キーに先行するすべてのサブツリーのパリティを追加します(これにより、左側のサブツリーのパリティを格納するという考え方が一般化されます)。ここで、このツリーでルックアップまたは更新を行う方法について考えてみましょう。ルックアップを行うには、以前から少し変更したバイナリツリールックアップアルゴリズムを使用します。各ステップで、各ノードで純粋に各サブツリーの左側にサブツリーのパリティを累積して、ツリーの上部から下部に向かってウォークします。この場合、ツリーの高さはなり、ノードごとに作業を行うため、ルックアップのコストはO (log k n )O (1 )O (log k n )kO(logkn)O(1)O(logkn)。
ただし、この設定では、更新を行うコストが増加します。特に、要素のパリティを変更する場合は、ツリーの最下部から最上部に向かって上に移動し、パス上のすべてのノードのすべてのキーの格納されたパリティを上方向に変更する必要があります。あるノードとあたりキー葉から上方の経路上のノードは、このような動作を行うコストがされるので、、これは遅すぎます。どういうわけかこの余分な項を排除できれば、ビジネスに参入できます。O (log k n )O (k log k n )= O (kkO(logkn)kO(klogkn)=O(klogklogn)k
この論文の洞察は次のとおりです。最初の問題について考えると、サイズ配列があり、プレフィックスパリティを計算できるようにしたいと考えました。私たちは、今持っているの各ノードで、我々はサイズのアレイ上のプレフィックスパリティ問題を解決できるようにする必要があり、進ツリー各ノードは、その下の層についての情報をキャッシュするので、それぞれを。上記のデータ構造では、プレフィックスパリティの配列を格納するだけで各ノードのプレフィックスパリティの問題を解決しました。つまり、更新を実行する必要がある場合、コストはです。このペーパーの洞察は、各ノードでより巧妙なデータ構造を使用することにより、これらの更新を大幅に効率的に実行できるということです。k k O (k )nkkO(k)
kk2kkkkk2kkkkikiO(logkn)O(logkn)O(1)
この論文の著者は、を選択すると、k=lgn2lgn22lgn2=lgn2n−−√=o(n)O(logkn)=O(lognloglgn2)=O(lognloglogn)o(n)O(n)
したがって、要約すると、アイデアは次のとおりです。
- k
- kk
- ツリーの各ノードでこの事前計算されたデータ構造を使用します。
- 選択k=lgn2O(lognloglogn)
- 事前計算が価値のあるものになるまで、各ノードで一時的な置換データ構造を使用することにより、事前の事前計算コストを回避します。
全体として、それは賢いデータ構造です。この質問をしてリンクしてくれてありがとう-その過程で多くのことを学びました!
O(logn)O(lognloglogn)