题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1031
题解:
后缀数组…
我们只需要用后缀数组 维护一下,把字符串复制一遍再求sa数组即可。
代码:
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int inf = 1 << 26;
const int size = 200005;
int wa[size], wb[size], wv[size], ws[size];
int r[size], sa[size];
char s[size], str[size];
int n, m;
int cmp(int *r, int a, int b, int l) {
return r[a] == r[b]&&r[a+l]==r[b+l];
}
void Da(int *r, int n, int m) {
int i, j, *x = wa, *y = wb, p, *te;
for ( int i = 0; i < m; i ++ ) ws[i] = 0;
for ( int i = 0; i < n; i ++ ) ws[x[i] = r[i]] ++;
for ( int i = 1; i < m; i ++ ) ws[i] += ws[i-1];
for ( int i = n-1; i >= 0; i -- ) sa[--ws[x[i]]] = i;
for ( j = 1, 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]];
for ( i = 0; i < m; i ++ ) ws[i] = 0;
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 ( te = x, x = y, y = te, p = 1, x[sa[0]] = 0, i = 1; i<n; i ++ ) {
x[sa[i]] = cmp(y, sa[i-1], sa[i], j)?p-1:p++;
}
}
}
int main(){
gets(str);
strcat(s, str);
strcat(s, str);
n = strlen(s);
s[n] = 1;
for ( int i = 0; i <= n; i ++ ) {
r[i] = s[i];
if(r[i] > m) {
m = r[i];
}
}
int l = strlen(str);
++ n;
Da(r, n, m+1);
for ( int i = 0; i < n; i ++ ) {
if(sa[i] < l) printf("%c", s[sa[i]+l-1]);
}
puts("");
return 0;
}