POJ3261ミルクパターン(接尾辞配列)

ファーマージョンは彼の牛によって与えられたミルクの品質は日々変化していることに気づきました。さらに調査では、彼は彼が1日から次へと牛乳の品質を予測することはできないものの、いくつかの規則的なパターンが毎日牛乳の品質であることを発見しました。

厳格な調査を行うために、彼は各ミルクサンプルが0と包括1,000,000の整数として記録されることにより、複雑な分類方式を発明した、と上の単一の牛からのデータを記録している  N  (1≤  N  日2万≤)。彼は同じ少なくともK(2≤繰り返し試料の最長のパターンを見つけることを望む  K  ≤  N)回。例えば、1 2 3 2 3 2 3 1回繰り返す3 2 3 2、 -これは、重複するパターンを含んでもよいです。

サンプルのシーケンスで最長の繰り返しサブシーケンスを見つけることによってファーマージョンを助けます。少なくとも一つのサブシーケンスは、少なくとも繰り返されることが保証されている  Kの時間を。

入力

1行目:二スペースで区切られた整数:  N  と  K 
線2 ...  N 1:  N  の整数、1行に1つずつ、日に牛乳の品質  、私が  上に現れる  I ライン目。

出力

行1:つ整数、最長パターンの長さは、少なくとも発生  のK  回

サンプル入力

8 2 
1 
2 
3 
2 
3 
2 
3 
1

サンプル出力

4

ソリューション:

タイトルはそれはKは、最長の長さを見つけるの回数よりも少ない表示されるようにあなたがストリング内の配列内で検索することを意味しています。

+接尾辞配列の二分法:接尾辞配列の高さアレイの使用の性質上、バイナリの答え。(二分法を参照する接尾辞配列を理解することは書く方法を知っている必要があります)

参照コード:

書式#include <iostreamの> 
書式#include < 文字列の.h> 
の#include <stdio.hに> 
する#include <math.h>の
書式#include <アルゴリズム> 
書式#include < 設定 >
 使用して 名前空間はstd;
INT A [ 20010 ]、HA [ 20010 ]。
INT SA [ 20010 ]、C [ 20010 ]、RA [ 20010 ]、X [ 20010 ]、Y [ 20010 ]、H [ 20010 ]。
ボイドビルド(int型のn、int型M){
     int型I、J、P。
    (i = 0 ; iがmを<; iは++)C [I] = 0 ;
    (i = 0 ; iがn <; iは++ ){ 
        X [i]は = A [I] + 1 ; 
        C [X [I]] ++ ; 
    } 
    のための(I = 1 iが++; iがm <)[I-C [I] + = C 1 ]。
    (i = 0 ; iがn <; I ++)はSAの[ - C [X [I]]] = I。
    (J = 1、J <N; J * = 2 ){ 
        P = 0 以下のための(I = NJ; iがn <; I ++)は、Y [P ++] = I。
        以下のための(I = 0;私は<N; iが++)場合(SA [I]> J =)をY [P ++] =のSA [I] - J。
        (i = 0 ; iがmを<; iは++)C [I] = 0 ;
        (i = 0 ; iがn <; iは++)のC [X [Y [I]]] ++ ;
        (i = 1 ; iがmを<; iは++)C [i]は+ = C [I- 1 ]。
        以下のための(I = N- 1、I> = 0 ; i--)のSA [ - Cの[X [Y [I]]]] = Y [i]は、
        スワップ(X、Y)
        X [SA [ 0 ] = 0 ; 
        M = 1 (i = 1 ; iがn <I ++は
        {
            もし(Y [SA [I]] == Y [SA [I- 1 ]] && Y [SA [I] + J] == Y [SA [I- 1 ] + J])×[SA [I] = M- 1  X [SA [I] = M ++ 
        } 
        であれば(M> = N)、ブレーク
    } 
} 
空隙高さ(int型n)を
{ 
     int型 I、J、K = 0 (i = 0 ; iが<= N; I ++)は、RA [SA [I] = I。
     (i = 0 ; iがn <; iは++ ){
           場合(K)k-- 
          J =のSA [RAの[I] - 1 ]。
          一方、([I + K] == A [J + K])は、k ++ ; 
          H [RA [I] = K。
     } 
} 
int型のチェック(int型 L、INT nは、INTのK){
     int型の合計= 1、MA = - 1 、I。
    (i = 1 ; iが<= N; iは++ ){
         場合(H [I]> = L){ 
            合計 ++ もし(MA <和)MA = 和。
        } 
        和= 1 
    } 
    戻り MA> = K。
} 
セット< 整数 > 秒;
設定 < 整数 > ::イテレータit。
INT のmain()
{ 
    int型は、I、N、K、M。
    scanf関数(" %d個の%のD "、&​​N&K)。
    (i = 0 ; iがn <; iは++ 
    { 
        scanf関数(" %のD "、&A [I])。
        s.insert([I])。
    } 
    、M = 0 以下のためには、(それがs.beginを()=;!それ= s.end();それ++)haの[メートル++] = * それ。
    以下のための(I = 0; iがN <; I ++)はAを[I] = LOWER_BOUND(HA、HA + M、A [I]) - ヘクタール。
    [N] = - 1 
    ビルド(N + 120005 )。
    高さ(N)
    int型、L = 1、R = 20005 、ミッド。
    一方、(L + 1 < R)
    { 
        半ば =(L + R)/ 2 もし(チェック(MID、N、K))L = ミッド。
        他の R = ミッド; 
    } 
    であれば(チェック(L、N、K))のprintf(" %d個の\ n " 、L)。
    のprintf("0 \ n " );
     戻り 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/songorz/p/11210403.html