フェイス質問
https://www.luogu.org/problem/P3804
問題の解決策
// luogu-判定部は、有効-O2 の#include <cstdioを> する#include <iostreamの> の#include <CStringの> に#define里登録int型 の#define N 1000050 使用して 名前空間はstd; チャーS [N]。 int型のn; int型 ANS = 0 ; 構造体SAM { int型 FF [N << 1 ]、CNT [N << 1 ]。 INT CH [N << 1 ] [ 26 ]。 INT LEN [N << 1 ]。 int型のTOT、最後。 int型のトン[N << 1]、[N << 1 ]。 インラインボイドコピー(INT NQ、INT Q){ ため(RI i = 0 ; iが< 26 ; iが++)CH [NQ] [I] = CH [Q] [I]; FF [NQ] =のFF [Q]。 } インラインボイド(伸びるINT O){ int型、P = 最後に、NP、Q、NQと、 NP = ++ TOT; LEN [NP] = LEN [P] + 1 。 最後 = NP。 一方、(!P && CH [P] [O])CH [P] [O] = NP、Pの=のFF [P]。 もし(!p)はFF [NP] =1 ; そうでなければ{ Q = CH [P] [O]。 もし(LEN [Q] == lenの[P] + 1)FF [NP] = Q。 他の{ NQ = ++ TOT; コピー(NQ、Q); LEN [NQ] = LEN [P] + 1 。 FF [NP] = FFの[Q] = NQ。 一方、(P && CH [P] [O] == Q)CH [P] [O] = NQ、P = FF [P]。 } } CNT [NP] = 1 。 } ボイドワーク(){ 用(RI i = 1 ; I <= TOT; iは++)トン[LEN [I]] ++; 用(RI I = 1トン[I] + =トン[1-; iが<= N I ++)は1 ]。 用(RI i = 1 ; I <= TOT; iが++)[トンLEN [I]] - ] = I。 用(RI iはTOTを=; I> = 1 ; i--)CNT [FF [I]]] + = CNT [i]が]。 用(RI i = 1 ; I <= TOT; iは++)場合(CNT [I]> 1)ANS = MAX(ANS、LEN [I] * CNT [I])。 } } SAM。 INT メイン(){ scanf関数(" %sの"、S + 1 )。 N = STRLEN(S + 1 )。 sam.tot = 1; sam.last = 1 。 用(RI I = 1 sam.extend(S [I] - ; iが<= N I ++)は' A ' ); ANS = 0 ; sam.work(); printf(" %d個の\ n " 、ANS)。 }