[] AHOI2013差(2)

フェイス質問

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 / = 2cnt-- ; 
  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 ; 
}

 

おすすめ

転載: www.cnblogs.com/shxnb666/p/11427279.html