bzoj1031(sa)

省选前练习模板系列;

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=400010;
int N,n,m,ra[maxn],sa[maxn],tp[maxn],tong[maxn],H[maxn];
char s[maxn];
int cmp(int x,int y,int w){return tp[x]==tp[y]&&tp[x+w]==tp[y+w];}
void rsort(){
    for(int i=0;i<=m;++i)tong[i]=0;
    for(int i=1;i<=n;++i)tong[ra[tp[i]]]++;
    for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
    for(int i=n;i>=1;--i)sa[tong[ra[tp[i]]]--]=tp[i];
}
void pre(){
    for(int i=1;i<=n;++i)ra[i]=s[i],tp[i]=i;
    m=300;rsort();
    for(int w=1,p=1,i;p<n;w+=w,m=p){
        for(p=0,i=n-w+1;i<=n;++i)tp[++p]=i;
        for(i=1;i<=n;++i)if(sa[i]>w)tp[++p]=sa[i]-w;
        rsort();swap(tp,ra);ra[sa[1]]=p=1;
        for(i=2;i<=n;++i)ra[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;
    }
    int j,k=0;
    for(int i=1;i<=n;H[ra[i++]]=k)
        for(k=k?k-1:k,j=sa[ra[i]-1];s[i+k]==s[j+k];++k);
}
int main(){
    scanf("%s",s+1);
    n=strlen(s+1);N=n;
    for(int i=1;i<n;++i)s[N+i]=s[i];
    n+=n-1;
    pre();
    for(int i=1;i<=n;++i)
    if(sa[i]<=N)printf("%c",s[sa[i]+N-1]);
    return 0;
} 
原文地址:https://www.cnblogs.com/dibaotianxing/p/8707631.html