#35. 后缀排序
这是一道模板题。
读入一个长度为 nn 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 11 到 nn。
除此之外为了进一步证明你确实有给后缀排序的超能力,请另外输出 n−1n−1 个整数分别表示排序后相邻后缀的最长公共前缀的长度。
输入格式
一行一个长度为 nn 的仅包含小写英文字母的字符串。
输出格式
第一行 nn 个整数,第 ii 个整数表示排名为 ii 的后缀的第一个字符在原串中的位置。
第二行 n−1n−1 个整数,第 ii 个整数表示排名为 ii 和排名为 i+1i+1 的后缀的最长公共前缀的长度。
样例一
input
ababa
output
5 3 1 4 2 1 3 0 2
explanation
排序后结果为:
- a
- aba
- ababa
- ba
- baba
正解:后缀数组
解题报告:
模板,第一次交才发现我原来的模板是个萎的,太恐怖了。。。
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 #ifdef WIN32 14 #define OT "%I64d" 15 #else 16 #define OT "%lld" 17 #endif 18 using namespace std; 19 typedef long long LL; 20 const int MAXN = 300011; 21 char ch[MAXN]; 22 int n,m,tot; 23 int wa[MAXN],wb[MAXN],wv[MAXN],c[MAXN]; 24 int rank[MAXN],height[MAXN]; 25 int sa[MAXN]; 26 27 inline int getint() 28 { 29 int w=0,q=0; 30 char c=getchar(); 31 while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar(); 32 if (c==‘-‘) q=1, c=getchar(); 33 while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar(); 34 return q ? -w : w; 35 } 36 37 inline void da(int m){ 38 int i,*x=wa,*y=wb; 39 for(i=1;i<=m;i++) c[i]=0; 40 for(i=1;i<=n;i++) c[x[i]=(ch[i]-‘a‘+1)]++; 41 for(i=1;i<=m;i++) c[i]+=c[i-1]; 42 for(i=n;i>=1;i--) sa[c[x[i]]--]=i; 43 for(int k=1,p;k<=n;k=k*2) { 44 p=0; 45 for(i=n-k+1;i<=n;i++) y[++p]=i; 46 for(i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k; 47 for(i=1;i<=m;i++) c[i]=0; 48 for(i=1;i<=n;i++) c[x[y[i]]]++; 49 for(i=1;i<=m;i++) c[i]+=c[i-1]; 50 for(i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i]; 51 swap(x,y); x[sa[1]]=1; p=1; 52 for(i=2;i<=n;i++) x[sa[i]]=(y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k])?p:++p; 53 if(p==n) break; m=p; 54 } 55 } 56 57 inline void calheight(){ 58 int i,j,k=0; 59 for(i=1;i<=n;height[rank[i++]]=k) 60 for(k?k--:0 , j=sa[rank[i]-1];ch[i+k]==ch[j+k];k++) ; 61 } 62 63 inline void work(){ 64 scanf("%s",ch+1); n=strlen(ch+1); 65 da(256); 66 for(int i=1;i<=n;i++) rank[sa[i]]=i; 67 calheight(); 68 for(int i=1;i<=n;i++) printf("%d ",sa[i]); 69 printf("\n"); 70 for(int i=2;i<=n;i++) printf("%d ",height[i]); 71 } 72 73 int main() 74 { 75 work(); 76 return 0; 77 }
时间: 2024-10-05 06:15:37