Poj_1_3
This topic is similar to spoj_687. For the basic ideas, refer to the article by Luo Sui and my spoj_687: http://www.cnblogs.com/staginner/archive/2012/02/06/2340521.html.
For the minimum Lexicographic Order condition, I did not think of a very good solution strategy, but the default R [L * I] is in the first loop section, then enumerate the positions of the first character in the first loop section. If the repetition number is equal to Max at this time, record the string. If the repetition number is larger than Max, update Max, after clearing the possible records, record the string. If it is smaller than Max, break the string directly, instead of enumerating the position of the first character in the first loop, because the current pair of characters cannot match, it cannot be included in the solution.
# Include <stdio. h>
# Include < String . H>
# Include <stdlib. h>
# Define Maxd 100010
# Define INF 0x3f3f3f
Char B [maxd];
Int N, R [maxd], sa [maxd], rank [maxd], height [maxd], wa [maxd], WB [maxd], WS [maxd], WV [maxd];
Int Best [ 20 ] [Maxd], Mm [maxd], Len [maxd], first [maxd], P;
Void Init ()
{
Int I;
For (I = 0 ; B [I]; I ++)
R [I] = B [I];
R [n = I] = 0 ;
}
Int CMP ( Int * P, Int X, Int Y, Int L)
{
Return P [x] = P [y] & P [x + L] = P [Y + L];
}
Int CMP1 ( Const Void * _ P,Const Void * _ Q)
{
Int I, * P = ( Int *) _ P, * q = ( Int *) _ Q;
For (I = 0 ; I <Len [* p] & I <Len [* q]; I ++)
{
If (R [first [* p] + I] <R [first [* q] + I])
Return - 1 ;
Else If (R [first [* p] + I]> r [first [* q] + I])
Return 1 ;
}
If (I = Len [* p])
Return - 1 ;
Return 1 ;
}
Void Da ( Int N,Int M)
{
Int I, j, P, * x = wa, * Y = WB, * t;
Memset (WS, 0 , Sizeof (WS [ 0 ]) * M );
For (I = 0 ; I <n; I ++)
++ Ws [x [I] = R [I];
For (I = 1 ; I <m; I ++)
WS [I] + = ws [I-1 ];
For (I = N- 1 ; I> = 0 ; I --)
Sa [-- ws [x [I] = I;
For (J = P = 1 ; P <n; j * = 2 , M = P)
{
For (P = 0 , I = N-J; I <n; I ++)
Y [p ++] = I;
For (I = 0 ; I <n; I ++)
If (SA [I]> = J)
Y [p ++] = sa [I]-J;
For (I = 0 ; I <n; I ++)
WV [I] = x [Y [I];
Memset (WS, 0 , Sizeof (WS [ 0 ]) * M );
For (I = 0 ; I <n; I ++)
++ Ws [wv [I];
For (I = 1 ; I <m; I ++)
WS [I] + = ws [I- 1 ];
For (I = N- 1 ; I> = 0 ; I --)
Sa [-- ws [wv [I] = Y [I];
For (T = x, x = Y, y = t, x [SA [ 0 ] = 0 , I = P = 1 ; I <n; I ++)
X [SA [I] = CMP (Y, sa [I- 1 ], Sa [I], j )? P- 1 : P ++;
}
}
Void Calheight ( Int N)
{
Int I, J, K = 0 ;
For (I = 1 ; I <= N; I ++)
Rank [SA [I] = I;
For (I = 0 ; I <n; height [rank [I ++] = K)
For (K? -- K: 0 , J = sa [rank [I]- 1 ]; R [I + k] = R [J + k]; k ++ );
}
Void Initrmq ( Int N)
{
Int I, j, X, Y;
For (Mm [ 0 ] =-1 , I = 1 ; I <= N; I ++)
Mm [I] = (I & (I- 1 ) = 0 ? Mm [I- 1 ] + 1 : Mm [I- 1 ];
For (I = 1 ; I <= N; I ++)
Best [ 0 ] [I] = I;
For (I =1 ; I <= mm [N]; I ++)
For (J = 1 ; J <= N -( 1 <I) + 1 ; J ++)
{
X = Best [I- 1 ] [J];
Y = Best [I- 1 ] [J + ( 1 <(I- 1 )];
Best [I] [J] = height [x] }
}
Int Askrmq ( Int X, Int Y)
{
Int T = mm [Y-x + 1 ];
Y = Y -( 1 <T) + 1 ;
X = Best [T] [x];
Y = Best [T] [Y];
Return Height [x] }
Int Calculate ( Int X, Int Y)
{
Int T;
X = rank [X], y = rank [y];
If (X> Y)
T = x, x = Y, y = T;
++ X;
Return Askrmq (x, y );
}
Void Printresult ( Int Max)
{
Int I, J, K;
If (Max = 1 )
{
K = inf;
For (I = 0 ; I <n; I ++)
If (R [I] <K)
K = R [I];
Printf ( " % C \ n " , K );
}
Else
{
For (I = 0 ; I <p; I ++)
WS [I] = I;
Qsort (WS, P, Sizeof (WS [ 0 ]), CMP1 );
For (I = 0 , K = ws [ 0 ]; I <Len [k]; I ++)
Printf ( " % C " , R [first [k] + I]);
Printf ( " \ N " );
}
}
Void Solve ()
{
Int I, J, K, P, max = 1 , Ans;
Da (n + 1 , 128 );
Calheight (N );
Initrmq (N );
For (I = 1 ; I <n; I ++)
For (J = 0 ; J + I <n; j + = I)
{
Ans = calculate (J, J + I );
K = J-(I-ans % I );
Ans = ANS/I + 1 ;
If (ANS <max- 1 | (ANS = max- 1 & Calculate (K, K + I) <I ))
Continue ;
For (K = ans = max- 1 ? K: J; j-k <I; k --)
{
Ans = calculate (K, K + I );
Ans = ANS/I + 1 ;
If (ANS <max)
Break ;
If (ANS> MAX)
{
Max = ans;
P = 0 ;
}
First [p] = K, Len [p] = ans * I;
++ P;
}
}
Printresult (max );
}
Int Main ()
{
Int T = 0 ;
For (;;)
{
Scanf ( " % S " , B );
If (B [ 0 ] = ' # ' )
Break ;
Printf ( " Case % d: " , ++ T );
Init ();
Solve ();
}
Return 0 ;
}