異なる部分文字列の数

異なる部分文字列の数
制限時間1.00秒
メモリ制限125.00メガバイト

トピックの背景

NOIは愚かな虐待を受けているので、それは、このような問題に遭遇したので、YJQ準備こんにゃくは、文字列について知ることができます。

タイトル説明

あなたは長さN、異なるサブストリングの必要な数の文字列を与えます

そして二つのサブ文字列がある場合にのみ、同じ長さまたは同じ長さではなく、いずれか一方と同じがない場合、我々は、二つの異なるサブストリングを定義します。

定義された部分文字列:文字列の連続した文字の元の文字列

入力形式

整数Nの最初の行

N分析に代表される、次の行の文字列

出力フォーマット

異なるサブストリングの数を表す整数を行

サンプル入力と出力

入力#1
。5
aabaaの
出力#1
。11
入力#2
。3
ABAの
出力#2
。5

説明/ヒント

使用して、64ビット整数を出力します

(具体的には、C ++やC選手が長い長い、パスカルプレイヤーがInt64型を使用するタイプを使用します)

入力ファイルが大きすぎるため、読み取ることが非常に効果的な方法を使用して(具体的には、C ++やCプレイヤーがCINを使用しない、パスカルプレイヤーがコントロールしていません)

データの30%、N \ル1000年N 。1 0 0 0

データの100%にN \ル^ 10 5 N 。1 0 。5


参考ブログ:https://www.luogu.org/blog/Elaborate/solution-p2408

#include <ビット/ STDC ++ H>
 のconst  int型 N = 4E5 + 50 使用して 名前空間はstdを、

構造体接尾辞配列
{ 
    INT SA [N]、順位[N]、高さ[N]、CNT [N]、A [N]、A2 [N]、N、M、*、X * Y。
    ボイドソート()
    { 
        ためint型 i = 0 ; iがmを<; iは++)CNTを[I] = 0 ;
        以下のためにint型 i = 0 ; iがN <、iは++)CNT [X [I]] ++ ;
        int型 i = 1 ; iがmは<; I ++)はCNT [I] + = CNT [I- 1 ]。
        以下のためのint型 I = N- 1をI> = 0 ; i--)のSA [ - CNT [X [Y [I]]]] = Y [i]は、
    } 
    ボイドビルド(CHAR * sで、int型C_SIZE)
    { 
        N = STRLEN(S)。
        M = C_SIZE。
        X = A1。
        Y = A2。
        以下のためにint型 i = 0 ; iがn <; iは++)X [I] = sの[I]、Y [i]は= I。
        X [N] = Y [N] = - 1 
        ソート(); 
        int型のk = 1 ; K <= N; kは<< =1 
        { 
            int型、P = 0 int型 Y [P ++] =; iがN <I ++はiはNK =)をI。
            以下のためにint型 i = 0 ; iは<N; iは++)場合(SA [I]> = K)Y [P ++] =のSA [i]は- kは、
            ソート(); 
            P = 0 
            STD ::スワップ(X、Y)
            X [SA [ 0 ] = 0 ;
            int型 iは= 1 ; iがN <I ++は
            { 
                場合(Y [SA [I] = Y [SA [1-!1!] || Y [SAの[I] + K] = Y [SA [I- 1 ] + K])p ++ 
                X [SA [I] = P。
            } 
            もし(P + 1 > = N)、ブレーク
            M = P + 1 
        } 
        のためのint型 I = 0 ; iがN <; I ++)は、ランク[SA [I] = I。
        高さ[ 0 ] = 0 ;
        int型のk = 0 以下のためにint型 i = 0 ; iがn <; iは++ 
        { 
            場合(K)k-- もし(ランク[I] == 0続けますint型 J = SA [ランク[I] - 1 ];
            一方(iは+ K <N && J + K <N && S [I + K] == S [J + K])は、k ++ ; 
            高さ[順位[I] = K。
        } 
    } 
} SA。


INT メイン()
{ 
    チャー S [N] = { 0 }。
    長い 長いLEN。
    scanf関数(" %D%S "、&LEN、S); 

    SA.build(S、256 )。

    長い 長い ANS =(+ lenのLENの* 1)/ 2; 
        
    以下のためにint型 i = 1 ; iがLEN <; iは++ 
    { 
        ANS - = SA.height [I]。
    } 

    のprintf(" %LLDする\ n "、ANS)。//
     返す 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/tian-luo/p/11261974.html