P2617動的評価を得ている(動的セグメントツリー処方の重量+フェンウィックツリー)

質問の意味:小さな間隔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 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/lwqq3/p/11315693.html