PAT(上級レベル)1057スタック

問題の解決策

  第一の方法:注文アレイツリー記録のスタックで[]の要素は、xの値の数は、[X]スタックツリーです。フェンウィックツリーのメンテナンスツリー[]、その後、バイナリ検索。

    第二の方法:暴力を探し、次に、ブロック、一定の長さの間隔の単位を使用して、スタック内の値の数を記録し、そして。

コード

// 树状数组+二分 
の#include <ビット/ STDC ++ H> 使用して名前空間STDを、
const int型 MAXN = 100010 ;
int型のツリー[MAXN]。
スタック < 整数 > STA;
アップデート(int型のp、int型ワット)。
int型の合計(int型P);
INT のmain()
{ int型N、W、左、右、中、K。
    文字列のOP; 
    scanf関数(" %のD "、&N)
    一方、(N-- 
    { 
        CIN
  
    >> オペアンプ;
        もし(OP [ 1 ] == ' U ' 
        { 
            scanf関数(" %のD "、&W)。
            sta.push(W)。
            (W更新1 )。
        } 
         
        { 
            場合(sta.size()< 1)のprintf(" 無効\ n " );
            そう であれば(OP [ 1 ] == ' O ' 
            { 
                のprintf(" %D \ n "、sta.top())。
                アップデート(sta.top() - 1 )。
                sta.pop(); 
            } 
            
            {  = 0 ;右= MAXN; K =(sta.size()+ 1)/ 2 一方(左<= 右)
                { 
                    半ば =(左+右)/ 2 もし(和(MID)> = k)の右=半ば1 他に     左=ミッド+ 1 ; 
                } 
                のprintf("%D \ n " )左; 
            } 
        } 
    } 
    システム(" 一時停止" );
     戻り 0 ; 
} 
ボイド更新(int型 P、INT W)
{ 
    ため(; P <MAXNあり; p + = P&( - P))
        ツリー[P] + = W; 
} 
int型の和(INT P)
{ 
    int型 ANS = 0 ;
     のための(; P> 0 ; P - = P&( - P))
        ANS + = ツリー[P];
     リターン年; 
}
// 分块 
の#include <ビット/ STDC ++ H> 使用して名前空間STDを、
const int型 MAXN = 100010、BLOCK_SIZE = 367 ;
INT CNT [MAXN]、ブロック[ 280 ]。
スタック < 整数 > STA;
無効 PUSH_POP(int型のインデックス、int型のV)。
int型の検索(int型k)は、
int型のmain()
{ int型のn、wは。
    文字列のOP; 
    scanf関数(" %のD "、&N)
    しばらく(N -
  
    
    { 
        CIN >> OP。
        もし(OP [ 1 ] == ' U ' 
        { 
            scanf関数(" %のD "、&W)。
            sta.push(W)。
            PUSH_POP(W 1 )。
        } 
         
        { 
            場合(sta.size()< 1)のprintf(" 無効\ n " );
            それ以外の 場合(OP [ 1 ] == ' O '  
            {
                のprintf("%dの\ n " 、sta.top())。
                PUSH_POP(sta.top() - 1 )。
                sta.pop(); 
            } 
               のprintf(" %dの\ n "、検索((sta.size()+ 1)/ 2 ))。
        } 
    } 
    システム(" 一時停止" )。
    リターン 0 ; 
} 
ボイド PUSH_POP(int型のインデックス、INT V)
{ 
  CNT [インデックス] + = V。
  ブロック[インデックス/ BLOCK_SIZE] + = V。
} 
INT検索(int型K)
{ 
  int型の和= 0、iが= 0 、インデックスを、
  一方、(和+ブロック[I] < k)の + =ブロック[I ++ ]。
  インデックス = BLOCK_SIZE * 私は、
  一方、1 
  { 
    場合(和+ CNT [インデックス]> = K)リターン指数。
    他の合計+ = CNT [インデックス]、インデックス++ ; 
  } 
}

おすすめ

転載: www.cnblogs.com/VividBinGo/p/12233459.html