0

セグメント ツリー構造を使用して、配列内の特定の値の頻度を計算する方法はありますか?

サイズ N の配列 A があり、配列のすべての要素 A[i] に値 0、1、または 2 が含まれているとします。次の操作を実行します。

  • 配列の任意の範囲 [a,b] のゼロの量を計算します
  • 配列の任意の範囲 [a,b] 内のすべての要素をインクリメント (mod 3) します

例: A = [0,1,0,2,0] の場合:

  • [2,4] の範囲には 0 が 1 つあるため、Query[2,4] は 1 を返す必要があります。
  • Incre[2,4] は、A を [0,2,1,0,0] に更新します。

これは、セグメント ツリーを使用して解決できる (この場合は、範囲の更新のために遅延伝播を使用する) 範囲合計クエリの問題によく似ていますが、セグ ツリー コードをこの問題に適応させることに成功しませんでした。通常の RSQ のようなツリー内の値では、値「3」を含む親ノード (たとえば) は何も意味しません。この情報では、この範囲に存在するゼロの数を抽出できないためです。

前もって感謝します!

--

編集:

セグメント ツリーは、配列に関連する区間をそのノードに格納するバイナリ ツリー構造です。葉ノードは実際の配列セルを格納し、各親ノードはその子の関数 f(node->left, node->right) を格納します。セグメント ツリーは、配列の範囲 [a,b] 内のすべての要素の合計を計算する範囲合計クエリを実行するためによく使用されます。この場合、親ノードによって計算される関数は、その子ノードの値の合計です。範囲合計クエリの問題を解決するためにセグツリーを使用したいのは、O(log n) で解決できるためです (範囲クエリで完全にカバーされるノードが見つかるまでツリーを下るだけです)。単純な O(n) アルゴリズム。

4

2 に答える 2

1

実際の配列値はリーフ (レベル L) に格納されるため、レベル L - 1 のノードに含まれるゼロの数を格納します (範囲 [0, 2] の値になります)。それ以外はすべて同じで、残りのノードは f(node->left, node->right) を as としてnode->left + node->right計算し、ゼロの数がルートに伝搬されます。

範囲をインクリメントした後、その範囲にゼロが含まれていない場合は、何もする必要はありません。ただし、その範囲にゼロがある場合、それらのゼロはすべて 1 になり、現在のノード (F と呼びます) の関数値はゼロになります。この値の変化は、関数値から F を減算するたびに根まで上方に伝播する必要があります。

于 2015-12-30T09:45:50.183 に答える