[POI2000]パブリック文字列

5以下の文字列を考えると、最長共通部分文字列を検索します

1ワット以下での長さの合計

 

いくつかの連続異なる文字で区切られた中間体に共通接続

高さを取得した後、半分の答えは、連続およびKの各期間の数を見つけ、Kプレフィックスによって決定されるアレイの高さ以上であり、各文字列から部分文字列が含まれています

$ O(nlogn)$

書式#include <cstdioを> 
する#include <CStringの> 
の#include <アルゴリズム>
 使用して 名前空間はstdを、
const  int型 MAXN = 10000 + 10 INTのN、M。
チャーS [MAXN]。 
int型SA [MAXN]、ランク[MAXN]、高さ[MAXN]。
int型の税[MAXN]、[MAXN] TP; 
インラインボイドtsort(){
     ためint型 iは= 1 ; I <= M; iは++)税[I] = 0 ;
    int型 I = 1を税金[順位[i]は] ++; iが<= N iが++) 以下のためにint型 I = 2 ; I <= M; iは++)税[I] + =税[I - 1 ]。
    以下のためにint型 I = N; I; i--)SA [税[順位[TP [i]は]] - ] =のTP [i]は、
} 
インラインブール CMP(intは * ARR、int型の L、int型の R、int型K){
     リターン [L] == ARR [R] && ARR [L + K] == ARR [R + ARR K]。
} 
ボイドsuffix_sort(){ 
    M = 128 以下のためにint型 i = 1 ; iが<= N; iは++)TPを[I] = I。
    ためにint型 i = 1 ; iが<= N; I ++)は、ランク[I] =のS [i]は、
    tsort(); 
    int型のk = 1、p = 0 ; p <nであり; kは<< = 1、M = P){ 
        P = K。
        int型 iは= 1 K + - TP [I] = N; iが= Kを<I ++)は、I
        int型 I = 1 ; <、= N iが++ i)があれば - (SA [i]がK)TP [++ P] =のSA [i]が> あり、k 
        tsort(); 
        スワップ(ランク、TP)。
        P =ランク[SAの[ 1]] = 1 以下のためにint型私= 2 ; iが<= N; iが++ 
            ランク[SA [I] = CMP(TP、SA [I - 1 ]、SA [i]を、k)は?P:++ のp; 
    } 
    のためのint型 I = 1、J、K = 0 ; iは= N <;高さ[順位[iが++] = K)
         のための(K k--:0、j個の=のSA [順位[1] - 1 ] ; S [J + K] == S [I + K]; ++ k個)。
} 
int型 L [ 10 ]、R [ 10 ]、合計[ 10 ] [MAXN] = { 0 }。
char型の温度[] = { " ' ' @ ' ' ' ' $ "0 };
INT Q [MAXN]、QCNT。
INT のmain(){
     int型N。
    scanf関数(" %のD "、&N)。
    N = 0 以下のためにint型 i = 0 ; iがNを<; iは++ ){ 
        L [I] = N + 1 
        scanf関数(" %sの"、S + 1 + N)。
        N + = STRLEN(S + 1 + N)。
        R [I] = N。
        S [ ++ N] = TEMP [I]。
    } 
    S [N - ] = 0 ; 
    suffix_sort(); 
    int型 iは= 0 ; iがNを<I ++は{)
         のためにINT J = L [i]は、jは<= R [i]は、J ++ 
            和[I] [順位[J] ++ ;
        INT J = 1 ; J <= N; J ++
            和[I] [J] I。+ =和[I]、[J - 1 ]。
    } 
    int型の L = 1、R = MAXN、中間、ANS = 0 int型 I = 0、R =分(R、R [I] - L [I] +; iがNを<I ++)は1 )。
    ブールフラグ。
    一方、(L <= R){ 
        ミッド = L + R >> 1 
        QCNT = 0 ;
        以下のためにint型 i = 1 ; iは= N <; iは++ ){
             場合(高さ[I] <MID)Q [++ QCNT] =
        } 
        ためint型 I = 2I <= QCNT。私は++ ){ 
            フラグ = INT J = 0 ; J <N; J ++)フラグ&=和[J] [Q [I] - 1 ] -和[J] [Q [I - 1 ] - 1 ]> 0 もし(フラグ)ブレーク
        } 
        であれば(フラグ){ 
            ANS = ミッド。
            L =ミッド+ 1 
        } 
         R =ミッド- 1 
    } 
    のprintf(" %d個の\ n " 、ANS)。
    リターン 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/ruoruoruo/p/11594284.html