---restore content starts---
Title Link: BZOJ-1692
Problem analysis
First of all, there is a relatively simple greedy idea: if the current remaining string of the two ends of the letter, choose a small letter, so it is clearly correct.
But if the letters are the same, how do we choose them?
At this point we are going to compare from the two sides to the inside, to see that one end of the string dictionary is small.
For example, this string abcdba, from the left to the inside is ABC. From right to Inside is ABD ... So just select the left-hand character.
So the direct comparison is O (n^2), we can use the Rank array of the suffix array to compare.
We add a delimiter to the string and then reverse the string back to the Rank array of the suffix array.
This allows you to quickly compare a prefix, a suffix of the dictionary order size, see the code.
such as ABCDBA, will be saved into ABCDBA#ABDCBA.
Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath > #include <algorithm>using namespace std;const int MaxL = 60000 + 15;int n;int A[maxl], Rank[maxl], Sa[maxl];int VA[MAXL], Vb[maxl], Vc[maxl], Sum[maxl];char S[MAXL], sout[maxl];inline bool Cmp (int *a, int x, int y, int l) {return (a[x ] = = A[y]) && (a[x + l] = = A[y + L]);} void DA (int *a, int n, int m) {int *x, *y, *t;x = VA; y = vb;for (int i = 1; I <= m; ++i) sum[i] = 0;for (int i = 1; i <= N; ++i) ++sum[x[i] = a[i]];for (int i = 2; I <= m; ++i) sum[i] + = sum[i-1];for (int i = n; i >= 1; i.) sa[sum[x[i]]- -] = I;int p, q;p = 0;for (int j = 1; p < n; j <<= 1, m = p) {q = 0;for (int i = n-j + 1; I <= n; ++i) y[++q ] = i;for (int i = 1; I <= n; ++i) {if (Sa[i] <= j) Continue;y[++q] = sa[i]-J;} for (int i = 1; I <= n; ++i) Vc[i] = x[y[i]];for (int i = 1; I <= m; ++i) sum[i] = 0;for (int i = 1; I <= n; ++i) ++sum[vc[i]];for (int i = 2; I <= m; ++i) sum[i] + = sum[i-1];for (int i = n; i >= 1; i.) sa[sum[vc[i]]--] = Y[i];t = x; x = y; y = t;x[sa[1]] = 1; p = 1;for (int i = 2; I <= n; ++i) x[sa[i]] = Cmp (y, sa[i], sa[i-1], j)? P: ++p;} for (int i = 1; I <= n; ++i) rank[sa[i]] = i;} int main () {scanf ("%d", &n), for (int i = 1; I <= n; ++i) {cin >> s[i]; A[i] = s[i]-' A ' + 1; A[2 * n-i + 2] = A[i];} A[n + 1] = 27; A[n * 2 + 2] = 28;da (A, n * 2 + 2, +); int L = 1, R = N, Top = 0;while (l <= R) {if (s[l]! = S[r]) {if (S[l] < s[r]) {Sout[++top] = s[l];++l;} else {Sout[++top] = s[r];--r;} Continue;} if (L = = r) {Sout[++top] = s[l];break;} if (Rank[l] < Rank[n * 2-r + 2]) {sout[++top] = s[l];++l;} else {Sout[++top] = s[r];--r;}} for (int i = 1; I <= Top; ++i) {printf ("%c", Sout[i]), if (i% = = 0) printf ("\ n");} return 0;}
---restore content ends---
[Bzoj 1692] [Usaco2007 Dec] Queue transform "suffix array + greedy"