把字符串复制一遍,用后缀数组排序,按顺序输出sa[i]<n的后缀中第n个字母即可。第一次后缀数组啊。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#define N 200010
using namespace std;
char s[N];
int r[N], sa[N], n;
namespace Get_Suffix
{
int wa[N], wb[N], ws[N], wv[N];
bool 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 *sa,int n,int m) {
int i, j, p, *x = wa, *y = wb, *t;
for(i=0;i<m;i++) ws[i] = 0;
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=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(t=x,x=y,y=t,x[sa[0]]=0,i=1,p=1;i<n;i++)
x[sa[i]] = cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
}
return;
}
}
int main()
{
scanf("%s",s);
n = strlen(s);
for(int i=0;i<n;i++) r[i+n] = r[i] = s[i];
r[2*n] = 0;
Get_Suffix::da(r,sa,2*n+1,128);
for(int i=0;i<2*n+1;i++)
if(sa[i]<n) putchar(r[sa[i]+n-1]);
putchar('\n');
return 0;
}