効果の対象に
あなたの文字列を与えます
部分文字列の場合、それは接頭辞と接尾辞の両方である場合
その長さの出力と、それは何回元の文字列の合計が登場しました
分析
これは、接頭辞と接尾辞同じ126Bの両方のために決定されます
その後、我々は唯一何度もありました[i]は異なるZのそれぞれを記録する必要があります
そして[I]の発生数に数が、すべてのZ [i]がそれぞれ有効、Z用の出力よりも大きいです
Z [i]の長さは、最長プレフィックスプレフィックスである場合ため
そして、Z未満[i]は、正当な接頭辞必要があります
コード
書式#include <iostreamの>
の#include <cstdioを>
する#include <CStringの>
の#include < 文字列 >
の#include <アルゴリズム>
書式#include <CCTYPE>
書式#include <cmath>
の#include <cstdlib>
書式#include <キュー>
の#include <CTIME>
#include <ベクトル>
の#include < 設定 >
の#include <地図>
の#include <積層>
使用して 名前空間STD。
チャー S [ 100100 ]。
int型 nは、]、CNT、ANS [ 100100 ]。
インラインボイドget_z(){
int型 I、J、K、L = 0、R = 0 。
用(i = 1 ; iがn <; iは++ ){
場合(I <= R)Z [I] =分(R-I + 1、Z [I- L])。
一方、(I + Z [i]が<N && S [Z [i]は] == S [Z [i]が+ i])とZ [I] ++ ;
もし(I + Z [1] - 1 > R)、R = I + Z [1] - 1、L = I。
}
}
int型のmain(){
int型I、J、K。
scanf関数(" %sの" 、S);
N =STRLEN(S);
get_z();
用(i = 1 ; iがn <; iは++ ){
和[Z [I]] ++ ;
もし(Z [i]が== NI)ANS [++ CNT] = Z [i]は、
}
のprintf(" %d個の\ n "、CNT + 1 )。
ソート(ANS + 1、ANS + CNT + 1 )。
以下のための(I = N- 1、I> 0 ; I - )の和[I] + =和[I + 1 ]。
用(i = 1 ; iは= CNT <; iは++)のprintf(" %D%D \ n "、ANS [i]は、和[ANS [I] + 1 )。
printf(" %D%D \ n "、nは、1 )。
リターン 0 ;
}