后缀数组习题集

suffix(i):从第i个字符开始的后缀

sa[i]:后缀数组,“排第几的是谁”,即suffix(sa[i])<suffix(sa[i+1]),1<=i<n。

ra[i]:名次数组,“你排第几”,ra[i]表示的是suffix(i)在所有后缀中从小到大排列的“名次”

height[i]:suffix(sa[i-1])和suffix(sa[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀。

对于j和k,设rank[j]<rank[j],则有:

suffix(j)和suffix(k)的最长公共前缀为height[ra[j]+1],height[ra[j]+2],height[ra[j]+3],...,height[rank[k]]中的最小值。

1、洛谷 P3809 【模板】后缀排序

参考这里,以后求后缀数组都用倍增法吧。

 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<cstdlib>
 8 #include<cctype>
 9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 const int MAXN=1e6+5;
28 char str[MAXN];
29 int n,m;
30 int sa[MAXN],ra[MAXN],height[MAXN];
31 int wa[MAXN],wb[MAXN],wc[MAXN],wd[MAXN];
32 int read()
33 {
34     int s=1,x=0;
35     char ch=getchar();
36     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
37     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
38     return x*s;
39 }
40 void GetSaRa(int n,int m)//倍增法 nlogn 
41 {
42     int i,j,p,*x=wa,*y=wb,*t;
43     for(int i=0;i<m;++i) wd[i]=0;
44     for(int i=0;i<n;++i) wd[x[i]=str[i]]++;
45     for(int i=1;i<m;++i) wd[i]+=wd[i-1];
46     for(int i=n-1;i>=0;--i) sa[--wd[x[i]]]=i;
47     for(j=1,p=1;p<n;j*=2,m=p)
48     {
49         for(p=0,i=n-j;i<n;++i) y[p++]=i;
50         for(i=0;i<n;++i) if(sa[i]>=j) y[p++]=sa[i]-j;
51         for(i=0;i<n;++i) wc[i]=x[y[i]];
52         for(i=0;i<m;++i) wd[i]=0;
53         for(i=0;i<n;++i) wd[wc[i]]++;
54         for(i=1;i<m;++i) wd[i]+=wd[i-1];
55         for(i=n-1;i>=0;--i) sa[--wd[wc[i]]]=y[i];
56         for(swap(x,y),p=1,x[sa[0]]=0,i=1;i<n;++i)
57         x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;
58     }
59 }
60 void GetHeight(int n)
61 {
62     int i,j,k=0;
63     for(i=1;i<=n;++i) ra[sa[i]]=i;
64     for(i=0;i<n;height[ra[i++]]=k)
65     for(k?k--:0,j=sa[ra[i]-1];str[i+k]==str[j+k];++k);
66 }
67 int main()
68 {
69     scanf("%s",str);
70     n=strlen(str);
71     str[n]='0';m=200;
72     GetSaRa(n+1,m);
73     //GetHeight(n); 
74     //for(int i=0;i<=n;++i) cout<<sa[i]<<' ';cout<<endl; //含末尾加的字符 
75     for(int i=1;i<=n;++i) cout<<sa[i]+1<<' ';cout<<endl;//不含末尾加的字符 
76     //for(int i=0;i<n;++i) cout<<ra[i]<<' ';cout<<endl;
77     //for(int i=2;i<=n;++i)cout<<height[i]<<' ';cout<<endl;    
78 }
View Code

猜你喜欢

转载自www.cnblogs.com/wangzhebufangqi/p/11317446.html