明学的白板 2017-12-16
将字符串复制一遍接在原串后面,然后后缀排序即可。
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> #define space putchar(' ') #define enter putchar('\n') using namespace std; typedef long long ll; template <class T> void read(T &x){ char c; bool op = 0; while(c = getchar(), c > '9' || c < '0') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x){ if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 400005; int n, buf1[N], buf2[N], sa[N], buc[N], rnk[N]; char s[N]; void suffix_sort(){ int *x = buf1, *y = buf2, m = 127; for(int i = 0; i <= m; i++) buc[i] = 0; for(int i = 1; i <= n; i++) buc[x[i] = s[i]]++; for(int i = 1; i <= m; i++) buc[i] += buc[i - 1]; for(int i = n; i; i--) sa[buc[x[i]]--] = i; for(int k = 1, p = 0; k <= n; k <<= 1, m = p, p = 0){ for(int i = n - k + 1; i <= n; i++) y[++p] = i; for(int i = 1; i <= n; i++) if(sa[i] > k) y[++p] = sa[i] - k; for(int i = 0; i <= m; i++) buc[i] = 0; for(int i = 1; i <= n; i++) buc[x[y[i]]]++; for(int i = 1; i <= m; i++) buc[i] += buc[i - 1]; for(int i = n; i; i--) sa[buc[x[y[i]]]--] = y[i]; swap(x, y), x[sa[1]] = p = 1; for(int i = 2; i <= n; i++) if(y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) x[sa[i]] = p; else x[sa[i]] = ++p; if(p >= n) break; } for(int i = 1; i <= n; i++) rnk[sa[i]] = i; } int main(){ scanf("%s", s + 1), n = strlen(s + 1); for(int i = 1; i <= n; i++) s[n + i] = s[i]; n *= 2; suffix_sort(); n /= 2; for(int i = 1; i <= 2 * n; i++) if(sa[i] <= n) putchar(s[sa[i] + n - 1]); enter; return 0; }