#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
char s[N];
int n, sa[N], rk[N << 1], oldrk[N << 1], id[N], cnt[N];//sa[i]表示排序后第i小的编号 rk[i]表示编号i的排名
int i, m, p, w;
void get_sa(){
for (i = 1; i <= n; ++i) ++cnt[rk[i] = s[i]];
for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
for (i = n; i >= 1; --i) sa[cnt[rk[i]]--] = i;
for (w = 1; w < n; w <<= 1) {
memset(cnt, 0, sizeof(cnt));
for (i = 1; i <= n; ++i) id[i] = sa[i];
for (i = 1; i <= n; ++i) ++cnt[rk[id[i] + w]];
for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
for (i = n; i >= 1; --i) sa[cnt[rk[id[i] + w]]--] = id[i];
memset(cnt, 0, sizeof(cnt));
for (i = 1; i <= n; ++i) id[i] = sa[i];
for (i = 1; i <= n; ++i) ++cnt[rk[id[i]]];
for (i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
for (i = n; i >= 1; --i) sa[cnt[rk[id[i]]]--] = id[i];
memcpy(oldrk, rk, sizeof(rk));
for (p = 0, i = 1; i <= n; ++i) {
if (oldrk[sa[i]] == oldrk[sa[i - 1]] &&
oldrk[sa[i] + w] == oldrk[sa[i - 1] + w]) {
rk[sa[i]] = p;
}else {
rk[sa[i]] = ++p;
}
}
}
// for (i = 1; i <= n; ++i) printf("%d ", sa[i]);
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) cin>>s[i];s[n+1]='#';
for(int i=1;i<=n;i++) s[i+n+1]=s[n-i+1];
n=2*n+1;
m = max(n, 300);get_sa();
int l=1,r=n/2+2;int now=1;string ans;
while(l<=(n/2)&&r<=n&&now<=n/2){
if(rk[l]<rk[r]) ans+=s[l],l++;
else ans+=s[r],r++;
now++;
}
// cout<<ans<<endl;
// int cnt=0;
for(int i=0;i<=n/2-1;i++){
printf("%c",ans[i]);
if((i+1)%80==0) printf("\n");
}
}
Best Cow Line G(后缀数组
最新推荐文章于 2022-11-23 16:04:09 发布