【模板】后綴數組


 注意x,y數組的意義

x[i]表示編號為i的后綴的第一關鍵字

y[i]表示第二關鍵字排名為i的后綴編號

h[i]表示編號為i的后綴與其前一名的最大公共前綴

height[i]表示排名為i的后綴與其前一名的最大公共前綴

h[i]>=h[i-1]-1

 

代碼打的比較丑,有時間重新打一遍

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=2000010;
4 int n,s[N];
5 int m,x[N],y[N],sa[N],cnt[N],rank[N];
6 int h[N],height[N];
7 char ss[N];
8 void build_sa(){
9 for(int i=0;i<n;i++) cnt[x[i]]++;
10 for(int i=1;i<m;i++) cnt[i]+=cnt[i-1];
11 for(int i=n-1;~i;i--) sa[--cnt[x[i]]]=i;
12 for(int i=0;i<m;i++) cnt[i]=0;
13 for(int k=1;k<=n;k<<=1){
14 int num=0;
15 for(int i=n-1;i>=n-k;i--) y[num++]=i;
16 for(int i=0;i<n;i++) if(sa[i]>=k) y[num++]=sa[i]-k;
17 for(int i=0;i<n;i++) cnt[x[i]]++;
18 for(int i=1;i<m;i++) cnt[i]+=cnt[i-1];
19 for(int i=n-1;~i;i--) sa[--cnt[x[y[i]]]]=y[i];
20 for(int i=0;i<m;i++) cnt[i]=0;
21 swap(x,y);
22 num=0;
23 x[sa[0]]=num;
24 for(int i=1;i<n;i++){
25 if(y[sa[i]]!=y[sa[i-1]]||y[sa[i-1]+k]!=y[sa[i]+k]) num++;
26 x[sa[i]]=num;
27 }
28 num++;
29 if(num>=n) break;
30 m=num;
31 }
32 for(int i=0;i<n;i++) rank[sa[i]]=i;
33 return;
34 }
35 void build_height(){
36 int t=0;
37 for(int i=0;i<n;i++){
38 if(t) t--;
39 if(!rank[i]) h[i]=0;
40 else{
41 while(s[i+t]==s[sa[rank[i]-1]+t]) t++;
42 h[i]=t;
43 }
44 height[rank[i]]=h[i];
45 }
46 return;
47 }
48 int main(){
49 scanf("%s",ss);
50 n=strlen(ss);
51 for(int i=0;i<n;i++){
52 if(ss[i]>='0'&&ss[i]<='9') s[i]=ss[i]-'0';
53 else if(ss[i]>='A'&&ss[i]<='Z') s[i]=ss[i]-'A'+10;
54 else s[i]=ss[i]-'a'+36;
55 x[i]=s[i];
56 }
57 m=62;
58 build_sa();build_height();
59 for(int i=0;i<n;i++) printf("%d ",sa[i]+1);
60 printf("\n");
61 for(int i=1;i<n;i++) printf("%d ",height[i]);
62 return 0;
63 }

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



【后綴數組模板】 后綴數組模板 后綴數組模板整理 后綴數組nlogn模板 后綴數組總結及模板 「模板」 后綴數組 【模板】后綴數組 后綴數組模板 后綴數組模板及解釋 模板_后綴數組
 
粤ICP备14056181号  © 2014-2021 ITdaan.com