トピックへのリンク:https://cn.vjudge.net/contest/318888#overview
質問の意味:ジョンは同様の牛乳生産は、常に彼は状況下での日変化に日から予測することができませんでしたが、彼は法律に変更があることを知っているものの、牛乳の品質は0からの整数で表され、変化していることに注意1,000,000は、今長さnの配列が与えられると、最大のシーケンスを見つける必要、配列は、少なくともk回繰り返され、それぞれの部分が重なっていてもよい、必要な最長の長さを生じます。重ね合わせることは、単純にk回最長の部分文字列を繰り返しています。
思考:OI紙09を直接添字アレイから<< - >>溶液のうちの強力なツールの文字列が、最初の2点Xに対する回答、及びサフィックスは、いくつかのグループに分け(各高さの値がX以上です)。違いは、ここではグループの数はサフィックスk以上である判断する存在することです。ある場合には、K同じサブストリングが条件を満たし、または存在しない場合があります。このアプローチの時の複雑さは、O(nlogn)です。
最も重要なことは、それがために、我々は答えを見つけるために行くことができ、鉛の半分の高さのユニークな性質のもので、グループ化操作の高さです。
慎重に先頭にこの文を理解して、あなたは理解することができます
この質問は、再度、離散注意されたデータ0-> 100万少し大きいので、
1の#include <stdio.hの> 2の#include <iostreamの> 3の#include <アルゴリズム> 4の#include < 文字列・H> 5の#include <STDLIB.H> 6の#include <math.h>の 7の#include <キュー> 8の#include < 設定 > 9 10 の#define 0x3f3f3f3f INFを 11 の#define <整数、整数> PII対 12 の#define LL長い長い 13 使って 名前空間STDを、 14 typedefの符号なしの長い 長いULL。 15 const int型 MAXN = 2E6 + 6 。 16 17 INT S [MAXN]。 18 INT SA [MAXN] Tは[MAXN]、T2 [MAXN]、[MAXN] C。 19 INT ランク[MAXN]、高さ[MAXN]。 20 21 空隙 build_sa(INT N、int型M) 22 { 23 INT I、J、* X = T、* Yが= T2と、 24 のために(i = 0 ; iがm <I ++は) 25個の C [I] = 0 ; 26 のために(i = 0 ; iがn <; iは++ ) 27 C [X [I] = sの[I]] ++ ; 28 のために(i = 1 ; iは<M; iは++ ) 29 C [I] + = C [I- 1 ]。 30 のための(I = N- 1、I> = 0 ; i-- ) 31 - [C [X [I]]] =のsa ;私 32 のための(int型のk = 1 ; K <= N; kは<< = 1 ) 33 { 34 のint、P = 0 。 35 のための(I =のNK、iがn <; iは++ ) 36 Y [P ++] = I。 37 用(i = 0 ; iは<N; iは++ ) 38 { 39 であれば(SA [I]> = K) 40 Y [P ++] =のSA [i]は- kは、 41 } 42 用(i = 0 ; iがm <; iは++ ) 43個の C [I] = 0 ; 44 のために(i = 0 ; iがn <I ++は) 45個の C [X [Yの[I]]] ++ ; 46 のために(i = 1 ; iは<M; iは++ ) 47 C [I] + = C [I- 1 ]。 48 以下のための(I = N- 1 ; iは> = 0 ; i-- ) 49 のSA [ - Cの[X [Y [I]]]] = Y [i]は、 50 スワップ(X、Y) 51 、P = 1 。 52 X [SA [ 0 ] = 0 ; 53 のために(i = 1 ; iがn <; iは++ ) 54 X [SA [i]は] = Y [SA [I- 1 ]] == Y [SA [i]は] && Y [SA [I- 1 ] + ?K] == Y [SAは、[I] + K] P- 1:P ++ 。 55 もし(P> = N) 56 ブレーク。 57 M = P。 58 } 59 } 60 61 62 ボイドのgetHeight(int型N){ 63 のint I、J、K = 0 。 64 のためには、(i = 1 ; iが<= N; iは++ ){ 65 ランク[SA [I] = I。 66 } 67 用(i = 0 ; iがn <; iは++ ){ 68 であれば(K) 69 k-- 。 70 J = SA [順位[1] - 1 ]。 71 しばらく(S [I + K] == S [J + K]) 72 K ++ 。 73 高さ[順位[I] = K。 74 } 75 } 76 77 int型N、K。 78 int型B [MAXN]。 79 80 空隙離散化は、(){ 81 のために(int型 i = 0 ; iがn = <; iは++ ){ 82件の B [i]は=のS [i]は、 83 } 84 ソート(B、B + N + 1 )。 85 INTのサイズ=一意(B、B + N + 1) -B; 86 のために(int型 I = 0 ; iが<= N; iが++ ){ 87の S [I] = LOWER_BOUND(B、B +サイズ、S [I]) - B。 88 } 89 } 90 91 ブールチェック(INT X){ 92 INT TOT = 1 。 93 のためには、(int型 i = 1 ; iは<N =、iは++ ){ 94 であれば(高さ[I]> = X) 95 TOT ++ 。 96 他{ 97 であれば(> = TOTK) 98 リターン 真。 99 TOT = 1 。 100 } 101 } 102 戻り TOT> = K。 103 } 104 105 INT のmain(){ 106 ながら(〜のscanf(" %D%dの"、&N&K)){ 107 のための(int型 iは= 0 ; iがN <; Iは++ ){ 108 のscanf(" %dの"、&S [I])。 109 } 110 S [N] = 0 ; 111 離散化()。 112 build_sa(N + 1、N + 1 )。 113 のgetHeight(N) 114 INTの L = 0、R = N、ミッド。 115 一方(L <= r)は{ 116 半ば=(L + R)>> 1 。 117 であれば(チェック(MID)){ 118 L =ミッド+ 1 。 119 } 120 他{ 121 R =半ば1 。 122 } 123 } 124 のprintf(" %d個の\ n " 、R)。 125 } 126 戻り 0 ; 127 }