luogu 5561 [セレステ-B]ミラーマジック接尾辞配列+ RMQ +マルチセット

アイデアは確かに問題ではありませんが、TLEは2点を持っている理由を私は知りません -

#include <ビット/ STDC ++ H> 
の#define N 2000006 
の#define setIO(S)freopenは(S ".IN"、 "R"、STDIN)
名前空間stdを使用。
マルチセット<整数> ID、LEN。    
マルチセット<整数> ::イテレータit。      
int型ARR [N]、ST [N]、長さ[N]、idxx [N]、N、M = 120。
文字列str [N]。               
名前空間SA 
{ 
    INT RK [N]、[N] TP、税金[N]、SA [N]、高さ[N]、ログ[N]、DP [N] [22]。       
    ボイドのqsort()
    { 
        ため(INT i = 0; I <= M; ++ I)税[I] = 0; 
        ++税[RK [i]は];(; iが<= N I ++ iは1 = INT)のために 
        (I 1 = int型; I <= M; ++ i)のための税金[I-1]〜[I] + =税。
        SA [税[RK [i]は]] TP - ] = TPの[I] - (I; I> = 1、I = N INT)のために、
    } 
    ボイドコンストラクト()
    {
        RK [I] = I TP [I] =のARR [i]は、(; iが<= N I ++ iは1 = INT)のために 
        qsort(); 
        (int型のK = 1; = N <K; << = 1〜K)のための
        { 
            INT P = 0。
            TP [++ P] = I;(; iが<= N I ++ I = N-K + 1の整数)のために 
            以下のために(INT I = 1; I <= N; ++ I)IF(SA [I]> k)はTP [++のP] = SA [I] -k。
            qsort()、スワップ(TP、RK)、RK [SA [1] = P = 1。
            (; iが<= N I ++ I = 2 INT)ため
                RK [SA [I] =(TP [SA [I-1]] == TP [SA [I]] && TP [SA [I-1 ] + K] == TP [SAの[I] + K])P:++ P。
            もし(P == n)をブレーク。
            M = P。
        } 
        int型のk = 0。
        (; iが<= N; iは1 = int型I ++)用RK [SA [I] = I。
        (I 1 = int型、iが<= N; I ++)のために
        {  
            あり、k - (k)の場合
            INT J = SA [RK [I] -1]。
            ながら(ARR [I + K] == ARR [J + K])++、K。
            高さ[RK [I] = K。
        } 
    } 
    ボイドRMQ()
    {    
        (I = 2をint型++ I; iが<= N)+1でログイン[I] =ログイン[1 I >>]。    
        DP [I] [0] =高さ[I](; iが<= N I ++ i = 1 INT)のために、
        (INT J = 1;(1 << J)<= N; ++ j)のための
            (; I +(1 << J)-1 <= N ++ iは1 = INT)のために
                、DP [I] [ J] =分(DP [I]、[J-1]、DP [iが+(1 <<(j-1))] [J-1])。
    } 
    インラインINT getmin(INT A、INT B)
    { 
        int型K =ログイン[B-A + 1]。    
        (DP [A] [K]、DP [B-(1 << K)+1] [K])分を返します。
    } 
}。
INTメイン()
{ 
    I、J、PP、NN、Q int型。  
    // setIO( "入力"); 
            TMP = ST [X] + L-1。        
    scanf関数( "%d個"、      
    用(i = 1; iは= PP <; ++ I)
    { 
        scanf関数( "%sの"、STR + 1)。
        NNの=のSTRLEN(STR + 1)。
        ST [I] = N + 1。
        ; '+ 1 - ARR [++ N] = STR [J](; J <= NN ++ J J = 1)のために   
        ARR [++ N] = 30。         
    } 
    SA ::コンストラクト()。
    SA :: RMQ();   
    scanf関数( "%のD"、&Q)。                   
    用(i = 1; I <= Q; ++ I)
    { 
        int型OPT。
        scanf関数( "%d個"、&OPT)。
        IF(OPT == 1)
        { 
            int型、X、L、R、TMP。   
            scanf関数( "%D%D%D"、およびX、&L&R)。
            id.insert(idxx [I])。                            

            長さ[I] = R-L + 1。
  
            len.insert(R-L + 1)。                

            INT A =(* id.begin())、B =(*( - id.end()))。   

            IF(A == B)
            { 
                のprintf( "%d個の\ n"、* len.begin())。              
            } 
            { 
                のprintf( "%d個の\ n"、分(* len.begin()、SA :: getmin(A + 1、B)))。        
            } 
        } 
        { 
            int型K。
            scanf関数( "%のD"、&K);     

            len.erase(len.lower_bound(長さ[K]))。      
            id.erase(id.lower_bound(idxx [K]))。         

            もし(len.empty()) 
            { 
                のprintf( "0 \ n"); 
                持続する;  
            } 

            INT A =(* id.begin())、B =(*( - id.end()))。     

            IF(A == B)
            { 
                のprintf( "%d個の\ n"、* len.begin())。
            } 
            { 
                のprintf( "%d個の\ n"、分(* len.begin()、SA :: getmin(A + 1、B)))。          
            } 
        } 
    } 
    0を返します。
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/11525390.html