パーティションとフェンウィックツリーのすべての間隔の問題で重要なアプリケーションを持っています
ツリーとして効率的な、しかし、比較ミスの考えではないEMMアレイブロック
最初のブロックは言いました:
情報シーケンスがSQRT(n)は、ブロックのN個に分割され、各ブロックデータは、セクション情報の後続のクエリを事前に加速します
コードの最初の部分:
const int型 MAXN = 5E5 + 50 。 INTの和[MAXN]、[MAXN]、L [MAXN]、R [MAXN]、[MAXN]属します。 int型のブロック、NUM; ボイドビルド(){ ブロック = SQRT(N)。 NUM = N /ブロック。もし(N%ブロック)NUM ++ 。 以下のために(INT iが= 1 ; I <= NUM; I ++ ) L [I] =(I- 1)*ブロック+ 1、R [I] = I * ブロック。 R [NUM] = N。 以下のために(INT iは= 1 ; I <= NUM; I ++ ){ 用(int型 ; J <= R [i]を、J = L [i]はJ ++ ) [J]属する = I、和[I] + = [J]。 } }
グローバル変数コードこれらの前処理が必要である。和[i]を表し、i番目のブロックとデータ(又は排他的でもこの種の製品、同じです)
A [i]はi番目のデータ、L [i]は、R [i]は、それぞれ、i番目のブロックインデックスエンドポイントについて、属するブロック[i]のために属するi番目のストレージ
前処理は、標識された一点修正/更新およびクエリコードセクションの後に:
インラインボイド更新(int型のx、int型のY){ [X] + = Y。 和[X]属する] + = Y。 } インラインINTクエリ(int型のx、int型のY){ int型 ANS = 0 。 もし([X] ==属し[Y]属する){ ため(INT I = X; I <= Y; I ++ ) ANS + = A [i]は、 戻り値は、ANS; } のための(int型 I <= R [X] [属する]; i = X iは++) ANS + = A [i]は、 用(INT I =属し[X] + 1 ; [Y]属するI <; I ++ ) ANS + = 和[I]。 以下のために(INT iがLに= [属する[Y]; I <= Y; I ++ ) ANS + = A [i]は、 戻り値は、ANS; }
前記単一点列データの更新データの変更には、添え字の合計がブロックyを増加させるために属し、xは
およびクエリー間隔[X、Y]、及び、ブロックここで加算され暴力
1. X、Yとき、同じブロック、横断加算
和に2のx、yが同じブロック内にない場合、横断xにX加算ブロックは、右境界、プラス和に属する[X + 1] [Y-1]は、ブロックの左端が属するYトラバースを合計Y
一点O(1)に変更時間複雑性O(SQRT(N))であります
qwq最初の書き込み要約を明日もう一度、フェンウィックツリーを書きました