Codeforcesラウンド#603(DIV 2) - E.エディタ(セグメントツリー)

質問の意味:命令は$ `` L「$は、マウスカーソルの移動は、(あなたが左端を持っている場合は$を移動しません$)1つの単位$を左に表しているとき、あなたに$を一連の命令の束を与えるために、とき命令$ `` R「$は、ユニットを移動する権利など、カーソル、他の文字$($のみ小文字と左括弧、右括弧$)$が、彼らは文字を入力する文字にカーソルを変更することを示していることを示しています配列の得られた括弧内のテキストは合法的である場合、各命令のために、出力の数は、ブラケットを入れ子最大出力電流のテキストは、$ $配列ルール出力サブブレース-1

アイデア:$ 1を使用して$左括弧、$ - 1 $は、セグメントツリーと三つの値を維持し、右括弧、$ 0 $が表す他の文字を表現する:間隔と$ $、間隔最大プレフィックスと$ IMAX $、間隔最小プレフィクスおよびW $ IMINドル。法的括弧シーケンスのために、私たちは次の2つの条件を満たしている必要があります。

  • 左右の括弧の同数、すなわち$ W = 0 $
  • 接頭辞配列ブラケットは$ \ GE 0 $ IMINすなわち、以上$ 0から$に等しいです

ブラケットの正当なシーケンスの場合、最大のネストの範囲を括弧、最大のプレフィックスと$ IMAX $、修正するための単一のポイントとクエリ間隔ツリーラインを維持するために必要であるが、各クエリの範囲は$ [1であるため、 N-] $は、ルートノードのセグメントによって表される間隔はわずか$ [1、N] $、それはワイヤセグメントツリーの単一のポイントを維持する、小文字、左括弧、右括弧を入力するときにカーソル位置の値対応する値に、同時に更新間隔と間隔最大プレフィックス、プレフィックスと最小間隔で、のように更新された特定のは、以下のとおり

  • $ = $間隔と間隔左右の間隔と$ + $
  • プレフィックスと最小$ =分($接頭辞及び最小間隔は$、$間隔左部と右部の最小$ + $と$接頭辞を左)$
  • 最大プレフィックスと$ = MAX($と最大$接頭間隔左は、$ $ + $間隔部分と右部分と最大プレフィックス$を左)$

$ [1、N] $括弧配列合法、違法出力$ $ -1、法的直接出力区間$ [1、N]の値を更新分析IMAXの$ $ $

#include <iostreamの> 
する#include <アルゴリズム> 
の#include <cstdioを> 
する#include <CStringの> 使用して名前空間をSTD。const int型 N = 1000010 ; 構造体ノード{
     int型、W L、R、。
    int型IMIN、IMAX; 
}。
ノードツリー[ 4 * N]。
整数nは、RES [N]。
チャーS [N]。ボイドビルド(int型 K、int型 LEF、int型リグ)
{ 
    ツリー[K] .L = LEF、ツリー[K] .R = リグ。
    もし
 
 
 
 
 

 
 
(ツリー[K] .L == ツリー[K] .R){ 
        ツリー[K] .W =ツリー[K] .imin =ツリーは[K] .imax = 0 リターン; 
    } 
    int型のミッド=(+リグLEF)/ 2 
    ビルド(K * 2 、LEF、半ば)。
    ビルド(K * 2 + 1、ミッド+ 1 、リグ)。
    ツリー[K] .W =ツリー[K * 2 ] .W +ツリー[K * 2 + 1 ] .W。
    ツリー[K] .imax = MAX(ツリー[K * 2 ] .imax、ツリー[K * 2 + 1  ] .imax)。
    ツリー[K] .imin = MAX(ツリー[K * 2 ] .imin、ツリー[K * 2 + 1 ] .imin)。
} 
 
ボイド change_point(int型 K、int型のx、int型Y)
{ 
    場合(ツリー[K] .L == ツリー[K] .R){ 
        ツリー[K] .W = Y。
        リターン; 
    } 
    INTミッド= /(木[K] .L +ツリー.R [K])2 もし(x <= MID)change_point(2 * K、X、Y)。
     change_point(2 * K + 1 、X、Y)
    ツリー[K] .W  =ツリー[K *2 ] .W +ツリー[K * 2 + 1 ] .W。
    ツリー[K] .imax = MAX(ツリー[K * 2 ] .imax、ツリー[K * 2 ] .W +ツリー[K * 2 + 1 ] .imax)。
    ツリー[K] .imin =分(ツリー[K * 2 ] .imin、ツリー[K * 2 ] .W +ツリー[K * 2 + 1 ] .imin)。
} 
 
int型のmain()
{ 
    scanf関数(" %D%S "、およびN、S + 1 )。
    ビルド(11 、N)
    int型 CUR = 1、LEN = STRLEN(S + 1 )。
    以下のためにINT iが= 1 ; I <= LEN; I ++ ){
         場合' ' == S [i])とchange_point(1、CUR、1 );
         他の 場合' ' == S [i])とchange_point (1、CUR、 - 1 )。
        そう であれば' L ' == S [I]){
             場合(CUR> = 2)cur-- 
        } 
         もし' R ' == S [i])とCUR ++  change_point(1、CUR、0 );
        もし0!=木[ 1 ] .W || 0 =ツリー[!1 ] .imin)RES [i]を= - 1 ;
        のres [I] =木[ 1 ] .imax。
    } 
    ためINT iは= 1 ; I <= LEN; I ++ ){ 
        のprintf(" %dの" 、RES [I])。
        printf(I == lenの?" \ n個""  " ); 
    } 
    戻り 0 ; 
}

おすすめ

転載: www.cnblogs.com/zzzzzzy/p/12115114.html