繰り返しk回最長の部分文字列を重複していてもよいです

トピックへのリンク: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 }

 

おすすめ

転載: www.cnblogs.com/-Ackerman/p/11332809.html