3678:OJとwangxz

説明

ある日、神ベンはインフォマティクスオンライン評価システム(オンライン裁判官)に来たwangxz。彼があるので、神は哲学♂学校を走ったので、彼は問題をするつもりはなかったです。彼はこれらの問題ことがわかりました

nに番号1とラベル付けされて直線的に配置され、各質問は、(<= 0であってもよい)難易度値を有するメッシュ。彼はこれらのトピック♂プレイで遊ぶことにしました。

1、彼は一つの場所で特定のトピックのより困難♂値の一部に差し込むことができます。

2、彼はタイトルのために(削除)♂を食べることができます。

3、彼は場所の主題の難しさの値を確認することができます。

n個の要素(エレメントのn個に1標識)の初期シーケンスを維持する、以下の操作をサポートしています。

、A + 1、A + 2、...、B:0 PAB(この配列の要素の0 <= p <=数)(<= B)は、位置PとP + 1つの整数位置の間に挿入され1、B。pが0である場合、配列は、前に挿入されています。

1 AB(1 <= A <= B <=この配列内の要素の数)、2、...、B-1、+ 1 + B要素位置を削除します。

2 P(この配列の要素の1 <= p <=番号)クエリ要素Pポジション。

入力

最初の行の入力は、2つの正の整数N(1 <= N <= 20000)、M(1 <= M <= 20000)、一連の動作および数の要素の最初の数を表す含みます。

次にnは整数、最初の配列要素。

続いて行をM、各行はSYMの整数であり、

SYM = 0の場合、次の非負整数p、二つの整数、bがあります。

もしSYM = 1、次の2つの正の整数、B。

SYM = 2は、次の正の整数pが存在する場合、

P、Xの意味及び範囲、yは、被写体の説明を参照します。

いずれの場合においても、これ以上100,000の配列の要素の総数を確実にします。

数はint型でカバーすべてのトピックを確認してください。

出力

各SYM = 2、要素クエリの位置を表す整数を含む出力ライン、。

サンプル入力

5 3
1 2 3 4 5
0 2 1 4
1 3 8
2 2

サンプル出力

2

ヒント

ソース

LiZitongから

スプレイ問題は、動的な処方箋を使用します

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、

構造体ツリー{
     INT LEN、サイズ、NUM、CH [ 2 ]、FA。
} T [ 120005 ]。

INTの根、TOT、N、M。

ボイド押し上げ(INT X){ 
    T [X] .size = T [T [X] .CH [ 0 ]サイズ+ T [T [X] .CH [ 1 ]サイズ+。T [X] .LEN。
} 

INT CHK(INT X){
     戻り T [T [X]の.Fa] .CH [ 1 ] == X。
} 

ボイド回転(INT X){
     int型Y = tの[X]の.Fa、Z = T [Y]の.Fa、K = CHK(X)= tのW [X] .CH [K ^ 1 ]。
    T [Y] .CH [K] = W。
    Tの.Fa [W] = Y。
    T [Z] .CH [CHK(Y)] =のX。
    T [X]の.Fa = Z。
    T [X] .CH [K ^ 1 ] = Y。
    T [Y]の.Fa =のX。
    突き上げ(Y)。
    突き上げ(X)。
} 

ボイドスプレイ(int型のx、int型ゴール= 0 ){
     ながら(!T [X]の.Fa = 目標){
         int型、Y = T [X]の.Fa、Z = T [Y]の.Fa。
        もし(Z!=目標)の場合(CHK(X)== CHK(Y))、回転(Y)。
        他の回転(x)は、
        (x)は、回転、
    } 
    もし(!ゴール)ルート=のX; 
} 

INT k番目(INT K){
     int型 CUR = ルート。
    一方、1 ){
         もし(T [T [CUR] .CH [ 0 ]]サイズ> = K)CUR = T [CUR] .CH [ 0 ]。
        そう であれば(T [T [CUR] .CH [ 0 ]]。サイズ+ T [CUR] .LEN <K)K-T = [T [CUR] .CH [ 0 ]]。サイズ+ T [CUR]。 LEN、CUR = T [CUR] .CH [ 1 ]。
        他に{ 
            K- T = [T [.CH]置く0 ]のサイズ;。
            IF(!K = 1 ){ 
                T [ ++ TOT =の.Fa 寄与する。
                【TOT] .CH [ 0 ] = tの[置く] .CH [ 0 ]。
                [TOT] .nu​​m = T [置く] .nu​​m。
                [T [] .CHを入れ0 ] FA = TOT。
                【TOT] .LEN = K- 1 
                .CH [[置く] 0 ] = TOTを。
                突き上げ(TOT)。
            } 
            IF(K!= Tが[置く] .LEN){ 
                T [ ++ TOT =の.Fa寄与する。
                【TOT] .CH [ 0 ] = tの[置く] .CH [ 1 ]。
                【TOT] .nu​​m = T .nu​​m + [置く] K。
                [T [] .CHを置く1 ] FA = TOT。
                【TOT] .LEN = T .len- [置く] K。
                .CH [置く] 1 ] = TOTを、
                突き上げ(TOT)。
            } 
            T [置く] .LEN = 1 ; T [置く] .nu​​m K- + = 1 ;
            戻り値のセット。
        } 
    } 
} 

のIntビルド(int型 L、INT R){
    INT半ば=(L + R)>> 1 もし(!L = MID)T [中間] .CH [ 0 ] =ビルド(L、ミッド1)、T [T [中間] [.CH 0 ] = FA。ミッドを、
    もし(!ミッド= R)T [中間] .CH [ 1 ] =(MID +ビルド1、r)を、T [T [中間] [.CH 1 ] = FA。ミッドを、
    腕立て伏せ(中旬)。
    戻る途中に、
} 

int型のスプリット(int型 L、INT R){ 
    L = k番目(L); R = k番目(R + 2 )。
    スプレイ(L)。
    スプレイ(R、L)。
    戻りR; 
} 

int型{main()の
    scanf関数(" %d個の%のD "、&​​N、&M)。
    T [ 1 ] .size = T [ 1 ] .LEN = 1 以下のためにint型 i = 1 ; iが<= N; iは++)のscanf(" %dの"、&​​Tを[I + 1 ] .nu​​m)、T [I + 1 ] .size = T [I + 1 ] .LEN = 1 
    T [N + 2 ] .size = T [N + 2 ] .LEN = 1 
    TOT = N + 2 
    ルート =ビルド(1、N + 2 )。
    同時に(M-- ){
         int型OPT。
        scanf関数(" %d個"、&OPT)。
        スイッチ(OPT){
             ケース 0 :{
                 int型のP、B。
                scanf関数(" %D%D%D "、&​​P、&、&B)。
                INTの CUR =スプリット(P + 1 、P)。
                T [ ++ TOT]の.Fa = CUR; T [CUR] .CH [ 0 ] = TOT。
                T [TOT] .nu​​m = A、T [TOT] .LEN = T [TOT] .size = B-A + 1 
                突き上げ(CUR);押し上げ(ルート)。                
                ブレーク ;
            } 
            ケース 1 :{
                 int型、B。
                scanf関数(" %D%dの"、&​​、&B)。
                INT CUR = スプリット(B)
                T [T [CUR] .CH [ 0 ]]、FA = T [CUR] .CH [ 0 ] = 0 
                突き上げ(CUR)。
                突き上げ(ルート)。                
                破ります; 
            } 
            ケース 2 :{
                 int型の P; scanf関数(" %のD "、&P)。
                int型 CUR =スプリット(P、P)。
                printf(" %d個の\ n "、T [T [CUR] .CH [ 0 ] NUM。);                
                破ります; 
            } 

        } 
    } 
    戻り 0 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/plysc/p/11360087.html