それはどのようなものを何フェンウィック木です

我々はフェンウィック木を学習する前にemmmmm、我々はlowbit(n)を演算、lowbit(N)の負でない整数値を知っておくべきことは、「全て1の最下位ビットの後ろに0」バイナリで、N =などの構成を定義されています10は、バイナリとして表現される((1010)2 \)\、次いで(2 \ lowbit(N)= 2 =(10))\、見掛け

\ [lowbit(N)= N \と、(\ SIM N +1)= N \ AND(-n)\]

だから我々はに順序を置く\(ログ(X)\)セル間、

    while(x > 0) {
        printf("[%d %d]\n", x - (x & -x) + 1, x);
        x -= x & -x;
    }

フェンウィックツリーデータ構造は、上記の考えに基づいている、基本的な目的は、プレフィックスと順序を維持することです。所定の配列のために、我々は、配列cを作成する、ここで、C [x]が格納された配列間隔[X - lowbit(X)+ 1、x]は全ての数字と、とのために、\(\和^ X_ {X - lowbit(X)+ 1} [I] \)

その後、我々は、最も基本的な操作を見て、それフェンウィックツリー

1.シングルポイントの変更、クエリーインターバル

タイトル説明

それは、列の数にはよく知られている場合は、次の2つの操作を実行する必要があります。

数xプラス1.

2.セクションの数を取得し、各

入力形式

最初の行は、2つの整数N、Mを含み、それぞれの列と操作の回数の合計数の数を表します。

数が初期値のIアイテムのi番目の列を表す第2のラインは、スペースで区切られたN個の整数を含みます。

次のMラインが3つの整数を含む次のように、それは、一つの操作を表します。

操作1:フォーマット:1つのXK意味:Xプラスkの数

操作2:フォーマット:2 XY意味:各区間の出力回数[X、Y]と

出力フォーマット

出力は、すべて2の演算結果である線の整数を含んでいます。


クエリおよびxについてプレフィックスに1であり、我々は今述べた方法に従う、それは、xのバイナリ表現における各ビットについて決定されるべきである1と同じである、[1]、[X]に\()N(ログ\)部分区間、及び各セル間の配列Cに格納されています。だから、コードを少し上に書き換えることができます(ログ(N)\)\の時間と内部クエリプレフィックス:

inline int ask(int x) {
    int ans = 0;
    for(; x > 0; x -= x & -x) ans += c[x];
    return ans;
} 

もちろん、区間[L、R]とすべての番号を照会するには、数えるだけです\((Rを尋ねる)-ask( L - 1)\)

シングルポイントのためにcが[X] [X]、および任意のノードの祖先アップ含む「および」その祖先ノードの全てに格納されている影響を与えることが多くの変更\(ログ(N)\)、aは我々は彼らに値cを個別に更新することができます。

inline void add(int x, int k) {
    for(; x <= n; x += x & -x) c[x] += k;
}

すべての操作の前に、我々は、配列のツリーを初期化する必要があります - 元のシーケンスのツリー状のアレイを構築するために

簡単にするために、我々の初期のアプローチが、それぞれ[i]は、読み取りが([i]は、Iを追加実行する ) 動作、時間複雑である\(O(nlogn)\) この方法は、一般的になっています十分。
そこに、より効率的な方法であり、直接Cプレフィックス方法で更新[x]は、時間複雑である\(O(N)\)が、この方法は、接頭辞のよりオープンな配列を必要とし

    for(int i = 1; i <= n; ++i) {
        read(a[i]);
        add(i, a[i]);
    }
    for(int i = 1; i <= n; ++i) {
        read(a[i]);
        sum[i] = sum[i - 1] + a[i];
    }
    for(int i = 1; i <= n; ++i) {
        c[i] = sum[i] - sum[i - (i & -i)];
    }

問い合わせの範囲、修飾の単一ポイント2

タイトル説明

それは、列の数にはよく知られている場合は、次の2つの操作を実行する必要があります。

各セクションに加えて、いくつかの数x 1

2.数の値を取得

入力形式

最初の行は、2つの整数N、Mを含み、それぞれの列と操作の回数の合計数の数を表します。

数が初期値のIアイテムのi番目の列を表す第2のラインは、スペースで区切られたN個の整数を含みます。

次のMラインが2又は4の整数を含んでいる次のように操作を示します。

操作1:フォーマット:1 XYK意味:区間[X、Y]各数k個プラス

操作2:フォーマット:2 xは意味:x値出力の数

出力フォーマット

出力は、すべて2の演算結果である線の整数を含んでいます。

おすすめ

転載: www.cnblogs.com/AK-ls/p/11607508.html