羅区P3809 [テンプレート]接尾辞ソート接尾辞配列

URL:https://www.luogu.org/problem/P3809

質問の意味:

辞書順にソートされた文字列のすべてのサフィックス。文字列の長さは、$ 1E6の$未満です。

ソリューション:

その後、原理は最初の開始位置は、2番目のキーワードとして$ I + 1 $最初のキーとして$ I $の接尾辞である、キーワードは、新しい最初のキーを取得するために結合される裸の接尾辞配列、$私は2番目の鍵として2 $を+、その後、乗算、続いて組み合わせます。特定の実装コードのコメントを参照してください。

参考ブログ:

https://www.cnblogs.com/victorique/p/8480093.html

https://www.luogu.org/blog/black-jokers/solution1-p3809

https://www.cnblogs.com/ezoiLZH/p/9607849.html

ACコード:

#include <ビット/ STDC ++ H.> 
使用して名前空間STD; 
のconst int型MAXN = 1000005; 
構造体接尾辞配列
{ 
    int型N-、M; 
    int型税[MAXN]、ランク[MAXN]、TP [MAXN]、SA [MAXN]; 
    // SAは[i]は= J、i番目の名前が最初からjのサフィックス(ただし、預金添字)
    //ランク[i]は= J、サフィックスjの初めから私は名前がある(と相反SA 、位置(値))
    // TP [i]は、第二は、最初からキーワードサフィックスI jのである(第2のキーワードにSAアレイ当量は、格納されたインデックスである)
    //税[I] = J、Iは(基数ソートの値であるときにタブを有する)Jを有するキーワードの最初の数を表し
    ; CHAR CH [MAXN] 
    //基数ソート)ボイドソート(
    { 
        (I 0 = int型のために、私は< = M; ++ I)//は浴槽クリア
            ;税[I] = 0を
        、対応するバレルのそれぞれに// I ++)は数から得られる; I <= N;(私は= int型1について私は最初のキーワードサフィックスが初段[i]の名前で、開始
        //このランキングの接尾辞が税務ある[ランク[I]] 
            ++税[ランク[I]] ; 
        については、(int型I = 1; I <=メートル; ++ I)/ /プラスバケットの前で、ソートが完了し、ランキングを取得するには
            税[I] + =税; [1-I。] 
        について(I = N-をint型; i>は= 1; - I)からi //サフィックスは、2番目のキーワードTPの接尾辞である[I]、税[ランク[TP [I]]] = jの私は2番目の鍵である
        接尾辞//単語最初のキーワードはそうjのサフィックスを持つ最初のキーワード、求めていると、すでに自分のランキングを知った後、基数ソートための接頭辞であり、入れ
        TPを対応@サフィックスのランキング[i]が減少ランクながら、記録されています。私は2番目のキーのサフィックスに最初のキー取るたびに
        、これは最初のキーワードに応じてソートの第2の鍵、の同等と同じであるように、最後のキーワードに最初の//サフィックスを第二のハードル場合
        //キーワードが同じではありませんした後、第1および第2のキーワードでソートされたことを確実にするために、この時点でより確か、最初の大きなキーワードです。
            SA [税[順位[TP [I]]] - ] = TPの[I]; 
    } 
    BOOL CMP(int型、int型B、INT K)
    { 
        // TPは今最後のランクであり、
        //段落を上記[I-1] SAから意味[i]とSAから開始すると、同じ順位、かどうか接尾辞の始まりである
        Jの添加は比較ランキングは、第2の鍵であることを意味した後、同じトークンの後に//アイテム。交差なし保証
        戻りTPを[A] == TP [B] && TP [A + K] == TP [B + K]; 
    { 
        N- = STRLEN(CH用+ 1)。 
    }
    get_saボイド()  
            ランク[SA [1] = P = 1; // ソートで行わ新しいSAに記録された空きランク対応関係
        (。; I <= N; INT I = 1 ++ I)のために
            、M = MAX(M、ランク[I]は= CH [I]は- '0')、TP [I] = Iであり; //最初のラウンドASCIIコードキーを押し、第2プレス番号キー
        ソート(); //基数ソートの最初のラウンド
        のために(int型、P = 0、J = 1、P <N; J << = 1、M = P) 
        { 
            P = 0; //クリア
            するため(= I int型1; iは= <jの、iは++)
                TP [P ++] = N-I-J +; //以下Jのこれらの後者の添え字i、のみそれ自体、底面にので、第2の鍵の長さを低減することによって増大される
            (私は= int型1; iについて<= N; I ++)は
                IF(SA [I]> J)
                    TPの[++ P] = SA [i]の-j ; // SA [I]> Jプルーフサフィックス長さI Jよりも大きい場合、TP [SA [i]は -j] サフィックスSAである[I] -j第2の鍵は、このしばらくまだオーダーのうち
            一種(); //第二ラウンドと基数ソートを超えて
            スワップ(ランク、TP); // TP 役に立たない、我々はTPにコピーされた情報をランク付けします。空きランクながら 
                順位[SA [I] = CMP(SA [I]、SA [-I 1。]、J)P:++しますか? P;
            (I 2 = int型、iが<= N; ++ i)について
        } 
    } 
}。
接尾辞配列のSA。
INTメイン()
{ 
    //scanf("%d",&sa.n)。
    scanf関数( "%sの"、sa.ch + 1)。
    sa.get_sa(); 
    (; I <= sa.n ++ iは1 = INT)のための
        「「):のprintf( "%d個の%のC"、sa.sa [i]は、(I == sa.n '\ n'は); 
    0を返します。
}

  

おすすめ

転載: www.cnblogs.com/Aya-Uchida/p/11361472.html
おすすめ