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