我々はフェンウィック木を学習する前に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の演算結果である線の整数を含んでいます。