フェイス質問
https://www.luogu.org/problem/P4248
問題の解決策
ここでは、接尾辞配列のアプローチを提供します。
#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> の#include <iostreamの> CONST INT N = 1000050 。 使用して 名前空間はstdを、 チャーS [N]。 INTのN、M、ランク[N]、SA [N]、税金[N]、TP [N]、高さ[N]。 構造体RMQ { int型ミン、LOC。 } R [N] [ 25 ]。 長い 長い和[N]。 長い 長い ANS = 0 ; ボイドcntsort(){ ため(int型 I = 0 ; I <= M; I ++)は税金[I] = 0; 用(int型 I = 1を税金[順位[i]は] ++; iが<= N iが++) 。 以下のために(int型 I = 1 ; I <= M; I ++)は税金[I] + =税[I- 1 ]。 以下のために(int型 I = N; I> = 1 ; i--)SA [税[順位[TPの[I]]] - ] =のTP [i]は、 } ボイドsuffixsort(){ M = 75 。 以下のために(int型 i = 1 ; iが<= N; iは++)ランクを[I] = sの[I] - ' 0 ' + 1、TP [I] = I。 cntsort(); 以下のための(int型W = 1、p = 0 ; p <N、M = P、W << = 1 ){ P = 0 。 以下のために(int型 I = 1のTP [++ P] = - W N +; iは<= W iは++)I。 以下のために(int型 iは= 1 ; iは<N =、iは++)場合(SA [I]> W)TP [++ P] = SA [I] - W。 cntsort(); スワップ(TP、ランク)。 ランク[SA [ 1 ] = P = 1 。 用(int型 I = 2 ; iが<= N iが++ ) ランク[SA [I] =(TP [SA [1-が1 ]] == TP [SA [I]] && TP [SA [I-1 ] W +] == TP [SA [I] + W])?P:++ のp; } } ボイドのgetHeight(){ int型のk = 0 。 以下のために(int型 i = 1 ; iが= <N; iは++ ){ 場合(K)k-- 。 int型 J = SA [ランク[I] - 1 ]; 一方、(S [I + K] == S [J + K])は、k ++ ; 高さ[順位[I] = K。 } } ボイドgetsum(){ int型私は、 和[ 0 ] = 0 。 用(i = 1 ; iが<= N; I ++)は和[I] =和[1-1 ] + N-SA [I] + 1 。 } ボイドgetrmq(){ int型私は、jは、 用(i = 1 ; iが<= N; iは++)R [I] [ 0 ] = (RMQ){高さ[i]は、I}。 用(i = 1 ; iは= < 20 ; I ++ ){ int型、L =(1つの << I)。 用(J = 1、J ++; J <= n)の場合(R [j]は[I- 1 ] .minh <R [J + L / 2 ] [I- 1 ] .minh)R [J] [I] = R [j]は[I- 1 ]。他 R [j] [i]とR [J + L / = 2 ] [I- 1]; } } ボイドは(解決int型 L、INT R){ int型私は、ミン= 0x7f7f7f7f、P、ミッド= L + Rを>> 1 。 INT LEN = 1、CNT = 0 。 一方、(LEN <= R-L + 1 * = LEN)2、CNT ++ 。 LEN / = 2。cnt-- ; RMQ R1 = R [L] [CNT]、R2 = R [R-LEN + 1 ] [CNT]。 もし(r1.minh < r2.minh){ P = r1.loc。 ミン = r1.minh。 } そうでなければ{ P = r2.loc。 ミン = r2.minh。 } 長い 長い SUM1 =和[P- 1 ] -sum 1- [ 2 ]、SUM2 =和[R] -sum [P- 1 ]。 ANS + = SUM1×(R-P + 1)+ SUM2×(P-L + 1) - 2 *(R-P + 1)* 1LL *(P-L + 1)* ミン。 もし(L <= P- 1解く(L、P)1 ;) もし(p + 1 <= R)を解決(P + 1 、R)。 } int型のmain(){ scanf関数(" %sの"、S + 1 )。 N = STRLEN(S + 1 )。 suffixsort(); getHeight(); getsum(); getrmq(); (解決2 、N)。 coutの << ANS << てendl; リターン 0 ; }