【UOJ 35】 后缀排序|后缀数组 *3

来源:互联网 发布:mac itunes怎么下载 编辑:程序博客网 时间:2024/05/17 08:17

可以在开始处理rank数组!

注意字符集大小

#include <cstdio>#include <cstring>using namespace std;const int MAXN=1e5+100;char s[MAXN];int n,rank[MAXN],sa[MAXN],tmp[MAXN],cnt[MAXN],sec[MAXN],height[MAXN];void get_sa(){int nn=0;for(int i=1;i<=n;i++) cnt[s[i]-'a'+1]++;//printf("fva");for(int i=1;i<=26;i++) cnt[i]+=cnt[i-1];for(int i=1;i<=n;i++) sa[cnt[s[i]-'a'+1]--]=i;nn=rank[sa[1]]=1;for(int i=2;i<=n;i++){if(s[sa[i]]!=s[sa[i-1]]) nn++;rank[sa[i]]=nn;}for(int i=0;i<=26;i++) cnt[i]=0;//printf("%d\n",nn);for(int k=1;k<=n&&nn<n;k<<=1){int top=0;for(int i=n-k+1;i<=n;i++) sec[++top]=i;for(int i=1;i<=n;i++) if(sa[i]>k) sec[++top]=sa[i]-k;for(int i=0;i<=nn;i++) cnt[i]=0;for(int i=1;i<=n;i++) cnt[rank[i]]++;for(int i=1;i<=nn;i++) cnt[i]+=cnt[i-1];for(int i=n;i>=1;i--) sa[cnt[rank[sec[i]]]--]=sec[i];top=tmp[sa[1]]=1;for(int i=2;i<=n;i++){if(rank[sa[i]]!=rank[sa[i-1]]||rank[sa[i]+k]!=rank[sa[i-1]+k]) top++;tmp[sa[i]]=top;}nn=top;for(int i=1;i<=n;i++) rank[i]=tmp[i];}int k=0;for(int i=1;i<=n;i++){if(k) k--;int j=sa[rank[i]-1];while(j+k<=n&&i+k<=n&&s[j+k]==s[i+k]) k++;height[rank[i]]=k;}}int main(){scanf("%s",s+1);n=strlen(s+1);get_sa();for(int i=1;i<=n;i++) printf("%d ",sa[i]);printf("\n");for(int i=2;i<=n;i++) printf("%d ",height[i]);return 0;}


0 0