質問の意味:小さな間隔kの修理依頼
ソリューション:それは接頭語であるため、メモリの需要間隔k個の時間接頭語の使用やアイデアに木の会長を使用して、我々はフェンウィックツリーを維持することをプレフィックスとより良いを使用することができます
しかし、ここでは一人一人が、実際にはそれのバージョンと木の線の太さではありません一人一人の目の前にある木の会長ではなく、共通の接続点されていないアレイ重み情報を保存するが、私はドットに
我々はこの点を削除する操作を変更して、ツリー上の点の配列に元の情報を更新する最初の時間は、コードを見て、少し良く理解して一緒にジャンプすることについて
この方法は、制限がオフラインしなければならないにも非常に強いです
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 MAXN = 1E5 + 2 。 INTのN、M、LEN、CNT。 INT [ 100005 ]。 int型 B [ 200005 ]。 int型の合計[MAXN * 400 ]。 int型の LS [MAXN * 400 ]。 int型の RS [MAXN * 400 ]。 int型T [MAXN]。 int型の温度[ 2 ] [ 50 ]。 int型TOT1、TOT0。 構造体ノード{ チャーOPT。 int型U、V、W; } E [ 100005 ]。 ボイド追加(INT&O、int型の L、int型の R、int型 K、int型V){ 場合(!O)= ++ CNT。 和[O] + = V。 INT半ば= L + R >> 1 。 もし(L == R)のリターン; 場合(K <= MID)を追加(LSを[O]、L、中、K、V)。 他(RSを[O]、ミッド+追加1 、R、K、V)。 } ボイド更新(int型のx、int型の POS、INTV){ 用(int型)(Tを追加[I]; iが<= n iは+ =(I&-i I = xを)1 、LEN、POS、V)。 } ボイド prepare_query(int型 L、int型R){ TOT1 = TOT0 = 0 。 以下のために(int型 I = Rを、I> = 1 ; I - =(I&-i))TEMP [ 1 ] [++ TOT1] =のT [i]は、 以下のために(int型 I = Lを、I> = 1 ; I - =(I&-i))TEMP [ 0 ] [++ TOT0] =のT [i]は、 } INTクエリ(INT L、int型の R、int型K){ 場合(L == R)戻りL。 INT半ば= L + R >> 1 。 int型のres = 0 ; 以下のために(int型 I = 1 ; I <= TOT1; iは++)RES + =和[LS [TEMP [ 1 ] [I]]]。 以下のために(int型 I = 1 ; I <= TOT0; I ++)RES - =和[LS [TEMP [ 0 ] [I]]]。 もし(RES> = K){ ため(int型 I = 1 ; I <= TOT1; iは++)TEMP [ 1 ] [I] =のLS [TEMP [ 1 ] [I]]。 以下のために(int型 I = 1 ; I <= TOT0; iは++)TEMP [ 0 ] [I] =のLS [TEMP [ 0 ] [I]]。 戻りクエリ(L、中、K)。 } 他{ ため(int型 I = 1 ; I <= TOT1; I ++)はTEMP [ 1 ] [I] = RS [TEMP [ 1 ] [I]]。 以下のために(int型 I = 1 ; I <= TOT0; iは++)TEMP [ 0 ] [I] = Rsを[TEMP [ 0 ] [I]]。 戻りクエリ(MID + 1、R、K - RES)。 } } チャーS [ 5 ]。 INT メイン(){ CNT = 0 。 scanf関数(" %d個の%のD "、&N、&M)。 以下のために(int型 i = 1 ; iが<= N; iが++)のscanf(" %dの"、および[I])、[I] = B [i]は、 LEN = N。 以下のために(int型 I = 1 ; I <= M; iは++ ){ scanf関数(" %sの" 、S); E [i]は.OPT = S [ 0 ]。 もし(E [i]の.OPT ==' Q ')のscanf(" %D%D%D "、&E [i]は.U、&E [I] .V、&E [I] .W)。 他{ scanf関数(" %d個の%のD "、&E [i]は.U、&E [I] .V)。 B [ ++ LEN] = E [I] .V。 } } ソート(B + 1、B + 1 + LEN)。 LEN =一意(B + 1、B + 1 + LEN) - B - 1 。 以下のために(int型 i = 1 ; iが++; iが<= N ){ int型TT = LOWER_BOUND(B + 1、B + 1 + LEN、[I]) - B。 アップデート(I、TT、1 )。 } のために(int型 I = 1 ; I <= M; iが++ ){ 場合(E [i]が.OPT == ' Q ' ){ prepare_query(E [I] .U - 1 、E [I] .V)。 printf(" %d個の\ n "、B [クエリ(1 、LEN、E [I] .W)])。 } 他{ int型の T1 = LOWER_BOUND(B + 1、B + 1+ LEN、[E [I] .U]) - B。 更新(E [I] .U、T1、 - 1 )。 [E [I] .U] = E [I] .V。 INT T2 = LOWER_BOUND(B + 1、B + 1 + LEN、[E [I] .U]) - B。 更新(E [I] .U、T2、1 )。 } } 戻り 0 。 }