Divide a string into three sections and then reverse the string to minimize the Lexicographic Order.
Question: because the number one in the question is the largest, you only need to find the minimum Suffix in the first cut. For the remaining part, it is very troublesome to come up with the method and the longest public prefix is required, comparison in three sections. The method on the Internet is to multiply the remaining strings, because in fact, the latter two strings form a loop, and the double method can be used to avoid discussion, so that rank can be used directly for comparison.
Method 1:
[Cpp]
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <string>
# Include <queue>
# Include <algorithm>
# Include <vector>
# Include <stack>
# Include <list>
# Include <iostream>
# Include <map>
Using namespace std;
# Define inf 0x3f3f3f
# Define M 210000
Int max (int a, int B)
{
Return a> B? A: B;
}
Int min (int a, int B)
{
Return a <B? A: B;
}
Int rank [M], height [M], sa [M];
Int ts [M], TV [M], ta [M], tb [M], r [M], mm [M], dp [20] [M];
Bool cp (int a, int B)
{
Return r [a] <r [B];
}
Bool cmp (int * y, int a, int B, int l)
{
Return y [a] = y [B] & y [a + l] = y [B + l];
}
Void da (int n)
{
Int I, j, * x = ta, * y = tb, m, p;
For (I = 0; I <n; I ++) y [I] = I;
Sort (y, y + n, cp );
For (I = 0; I <n; I ++) sa [I] = y [I];
X [sa [0] = 0;
P = 1;
For (I = 1; I <n; I ++)
{
If (r [sa [I] = r [sa [I-1]) x [sa [I] = p-1;
Else x [sa [I] = p ++;
}
M = p;
For (j = 1, p = 1; p <n; j * = 2, m = p)
{
P = 0;
For (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 <m; I ++) ts [I] = 0;
For (I = 0; I <n; I ++) TV [I] = x [y [I];
For (I = 0; I <n; I ++) ts [TV [I] ++;
For (I = 1; I <m; I ++) ts [I] + = ts [I-1];
For (I = n-1; I> = 0; I --) sa [-- ts [TV [I] = y [I];
Swap (x, y );
P = 1;
X [sa [0] = 0;
For (I = 1; I <n; I ++)
{
If (cmp (y, sa [I-1], sa [I], j) x [sa [I] = p-1;
Else x [sa [I] = p ++;
}
}
}
Void calh (int n)
{
Int I, k;
For (I = 1; I <= n; I ++) rank [sa [I] = I;
K = 0;
For (I = 0; I <n; I ++)
{
Int tmp = sa [rank [I]-1];
For (; r [I + k] = r [tmp + k]; k ++)
;
Height [rank [I] = k;
K? -- K: 0;
}
}
Void initrmp (int n)
{
Int I, j, tmp;
Mm [0] =-1;
For (I = 1; I <= n; I ++) mm [I] = (I & (I-1 ))? Mm [I-1]: mm [I-1] + 1;
For (I = 1; I <= n; I ++) dp [0] [I] = height [I];
For (I = 1; I <= mm [n]; I ++)
{
Tmp = 1 <(I-1 );
For (j = 1; j <= n & j + tmp <= n; j ++)
Dp [I] [j] = min (dp [I-1] [j], dp [I-1] [j + tmp]);
}
}
Int lcp (int a, int B)
{
A = rank [a], B = rank [B];
If (a> B) swap (a, B );
A ++;
Int l = mm [B-a + 1];
B-= (1 <l)-1;
Return min (dp [l] [a], dp [l] [B]);
}
Int main ()
{
Int I, n, st1;
Scanf ("% d", & n );
For (I = n-1; I> = 0; I --)
{
Scanf ("% d", & r [I]);
}
R [n] =-inf;
Da (n + 1 );
Calh (n );
Initrmp (n );
Int mi = inf;
For (I = 2; I <n; I ++)
{
If (rank [I] <mi)
{
Mi = rank [I];
St1 = I;
}
}
Int rec = 1;
For (I = 2; I <st1; I ++)
{
If (lcp (rec, I) <st1-i)
{
If (rank [I] <rank [rec])
Rec = I;
}
Else
{
If (lcp (rec + (st1-i), 0) <I-rec)
{
If (rank [0] <rank [rec + st1-i])
Rec = I;
}
Else
{
If (rank [I-rec] <rank [0])
Rec = I;
}
}
}
For (I = st1; I <n; I ++)
Printf ("% d \ n", r [I]);
For (I = rec; I <st1; I ++)
Printf ("% d \ n", r [I]);
For (I = 0; I <rec; I ++)
Printf ("% d \ n", r [I]);
}
Method 2:
[Cpp]
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <string>
# Include <queue>
# Include <algorithm>
# Include <vector>
# Include <stack>
# Include <list>
# Include <iostream>
# Include <map>
Using namespace std;
# Define inf 0x3f3f3f
# Define M 410000
Int max (int a, int B)
{
Return a> B? A: B;
}
Int min (int a, int B)
{
Return a <B? A: B;
}
Int rank [M], height [M], sa [M];
Int ts [M], TV [M], ta [M], tb [M], r [M], mm [M], dp [20] [M];
Bool cp (int a, int B)
{
Return r [a] <r [B];
}
Bool cmp (int * y, int a, int B, int l)
{
Return y [a] = y [B] & y [a + l] = y [B + l];
}
Void da (int n)
{
Int I, j, * x = ta, * y = tb, m, p;
For (I = 0; I <n; I ++) y [I] = I;
Sort (y, y + n, cp );
For (I = 0; I <n; I ++) sa [I] = y [I];
X [sa [0] = 0;
P = 1;
For (I = 1; I <n; I ++)
{
If (r [sa [I] = r [sa [I-1]) x [sa [I] = p-1;
Else x [sa [I] = p ++;
}
M = p;
For (j = 1, p = 1; p <n; j * = 2, m = p)
{
P = 0;
For (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 <m; I ++) ts [I] = 0;
For (I = 0; I <n; I ++) TV [I] = x [y [I];
For (I = 0; I <n; I ++) ts [TV [I] ++;
For (I = 1; I <m; I ++) ts [I] + = ts [I-1];
For (I = n-1; I> = 0; I --) sa [-- ts [TV [I] = y [I];
Swap (x, y );
P = 1;
X [sa [0] = 0;
For (I = 1; I <n; I ++)
{
If (cmp (y, sa [I-1], sa [I], j) x [sa [I] = p-1;
Else x [sa [I] = p ++;
}
}
}
Void calh (int n)
{
Int I, k;
For (I = 1; I <= n; I ++) rank [sa [I] = I;
K = 0;
For (I = 0; I <n; I ++)
{
Int tmp = sa [rank [I]-1];
For (; r [I + k] = r [tmp + k]; k ++)
;
Height [rank [I] = k;
K? -- K: 0;
}
}
Int main ()
{
Int I, n, st1;
Scanf ("% d", & n );
For (I = n-1; I> = 0; I --)
{
Scanf ("% d", & r [I]);
}
R [n] =-inf;
Da (n + 1 );
Calh (n );
Int mi = inf;
For (I = 2; I <n; I ++)
{
If (rank [I] <mi)
{
Mi = rank [I];
St1 = I;
}
}
For (I = st1; I <n; I ++)
Printf ("% d \ n", r [I]);
Int rec = 1;
For (I = 0; I <st1; I ++)
{
R [I + st1] = r [I];
}
R [2 * st1] =-inf;
Da (st1*2 + 1 );
Calh (2 * st1 );
Mi = inf;
For (I = 1; I <st1; I ++)
{
If (rank [I] <mi)
{
Mi = rank [I];
Rec = I;
}
}
For (I = rec; I <st1 + rec; I ++)
{
Printf ("% d \ n", r [I % st1]);
}
}
Author: Wings_of_Liberty