140接尾辞配列をacwing

質問は、表面:

接尾辞配列(SA)は、通常二倍または我々の議論の範囲を超えているDC3アルゴリズム、重要なデータ構造です。

この問題では、我々は、高速行を使用する場合、ハッシュは、単純なバイナリで実現O N- L O G 2 N- 接尾辞配列を探しているO(Nlog2N)。

具体的には、長さの文字列のn S(添字0〜N-1)が与えられると、我々は整数K(使用でき0 K < NサフィックスS(0≦k個の文字列Sを<N) 〜N-1)。

すべてのサフィックス文字列S辞書式順序に従ってランク付け添え字iは、[i]はSAと呼ばれています。

さらに、我々は接尾ランキング添え字i-1、iの順位をされて検討し、最長の共通のプレフィックスの長さは、両方の[i]の高さと呼ばれます。

私たちの仕事は、2つの配列SAと高さを見つけることです。

入力形式

長さ30万を超えていない文字列を入力します。

出力フォーマット

最初のラインアレイSA、スペースで区切られた隣接する二つの整数。

第二のラインアレイの高さ、スペースで区切られた隣接する二つの整数は、我々は、[1] = 0の高さを必要とします。

サンプル入力:

ponoiiipoi

出力例:

9 4 5 6 2 8 3 1 7 0
0 1 2 1 0 0 2 1 0 2
ソリューション:
2つの星の最長プレフィックスサフィックス初めの2、書き込みのソートするソート機能に応じて、
書式#include <iostreamの> 
の#include <アルゴリズム> 
書式#include <CStringの>
 に#define ULL符号なしの長い長い
 使用して 名前空間はstdを、
CONST ULLの基地 = 131 constの ULL INT_MIN = - 1E6; 
ULL H [ 300010 ]、P [ 300010 ]。
int型の SA [ 300010 ]。int型のn;
チャー STR [ 300010 ]。
ULL GETint型 L、INT R)
{ 
    戻り H [R] -h [1- 1] * P [R-L + 1 ]。
} 
INT get_max(int型int型B)
{ 
    int型の L = 0INTの R =分(N-A + 1、N-B + 1 )。
    一方、(L < R)
    { 
        int型ミッド=(R + L + 1)>> 1 もし取得(、A +ミッド1!)= 取得する(B、B +ミッド1))、R =ミッド1 
        リットル = ミッド; 
    } 
    戻りL。 
}
BOOL CMP(int型 A、int型 B)// ソート機能
{
     int型 L = get_max(A、B);
     int型 > N-INT_MIN :? STR [A + AV = A + L L];
     int型 BV = B + L> N-? INT_MIN:STR [B + L]は、
     戻り AV < ; //昇順; BVを
} 
int型のmain()
{ 
    scanfの(" %のS "、STR + 1 ;)
    N- = STRLEN(STR + 1); P [ 0 ] = 。1 ;
     のためのINT I = 1 ; I <= N; I ++は
    { 
        H [I] = hの[I- 1 ] * 基底 + STR [I] - ' ' + 1 
        P [I] = P [I- 1 ] * 基地; 
        SA [I] = I。
    } 
    ソート(SA + 1、SA + N + 1 、CMP)。
    以下のためにint型 i = 1 ; iが<= N; iは++)のprintf(" %dの"、SAを[I] - 1 )。
    プット("" );
    以下のためのint型 I = 1私は++; iが<= N
    { 
        もし(I == 1)のprintf(" 0 " )。
        
        のprintf(" %dの"、get_max(SA [i]は、SA [I- 1 ]))。
    } 
    プット("" )。
    リターン 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/flyljz/p/11649133.html
おすすめ