最長の繰り返し部分文字列を重複しないかもしれません

トピックへのリンク:https://cn.vjudge.net/contest/318888#overview

 

問題の意味:ピアノ音色系列Pを考えるには、[値は(88から1)の範囲]、今満たすシーケンスを見つけることが必要です

1、少なくとも5の長さ

図2は、配列がトランスポーズすることができ、すなわち、二つのサブ配列の存在は、一つのサブ配列はプラスを満たし/マイナス他の配列の数とすることができます

3、配列は、2つの交差する部分を持つことができません。

質問の意味は、単に非重複最長のサブストリングの重複を探しています

 

アイデア:

実際には、この質問が重複してしまうことがあり、最大再送要求は最長のようなサブストリング。我々は、最長の塩基は限り最長のサブストリングがないようにSA [i]は、それに一致するかを決定するために繰り返すように重なっていてもよい次いで見つけます

 

  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。
78  ブールチェック(int型K){
 79      INT maxsa = SA [ 0 ]、minsa = SA [ 0 ]。
80      のためには、int型 i = 1 ; iは<N; iは++ ){
 81          であれば(高さ[I]> = K){
 82              minsa = 分(SA [i]は、minsa)。
83              maxsa =MAX([I]において、maxsa)。
84          }
 85          {
 86              であれば(時間maxsa> = K)
 87                  リターン 88              maxsa = [I]。
89              minsa = [I]において、
90          }
 91      }
 92      であれば(時間maxsa> = K){
 93          リターン 94      }
 95      リターン 96  }
 97  
98  INT メイン(){
 99      (〜のscanf(" %dの"!、&N)&& N = 0 ){
 100          のためにint型 i = 0 ; iがn <; iは++ ){
 101              のscanf(" %dの"、&S [I])。
102          }
 103          のためにint型 i = 0 ; iがn <; iは++ ){
 104              もし(I == N- 1 105の                  S [I] = 0 ;
106              他の
107                  S [I] = sの[I + 1 ] -s [I] + 100;
108          }
 109          build_sa(N、200 )。
110          のgetHeight(N- 1 )。
111          INTの L = 0、R = N、ミッド。
112          一方(L <= r)は{
 113              半ば=(L + R)>> 1 114              であれば(チェック(MID)){
 115                  L =ミッド+ 1 116              }
 117              {
 118                  R =半ば1 119              }
 120         }
 121          であれば(R < 4 ){
 122              のprintf(" 0 \ n " );
123          }
 124          {
 125              のprintf(" %d個の\ n "、R + 1 )。
126          }
 127      }
 128      戻り 0 ;
129 }

 

おすすめ

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