后缀数组

Posted jaydenouyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后缀数组相关的知识,希望对你有一定的参考价值。

https://blog.csdn.net/qq_35640373/article/details/70168683

 1 //hdu 3518
 2 #include <iostream>
 3 #include <string.h>
 4 #include <stdlib.h>
 5 #include <cmath>
 6 #define LL long long
 7 using namespace std;
 8 
 9 #define maxn 1020
10 int max(int x,int y){ return x>y?x:y;}
11 int min(int x,int y){ return x<y?x:y;}
12 int wa[maxn],wb[maxn],wv[maxn],WS[maxn];
13 
14 int cmp(int *r,int a,int b,int l){
15     return r[a]==r[b]&&r[a+l]==r[b+l];
16 }
17 
18 void da(int *r,int *sa,int n,int m){
19     int i,j,p,*x=wa,*y=wb,*t;
20     for(i=0;i<m;i++) WS[i]=0;
21     for(i=0;i<n;i++) WS[x[i]=r[i]]++;
22     for(i=1;i<m;i++) WS[i]+=WS[i-1];
23     for(i=n-1;i>=0;i--) sa[--WS[x[i]]]=i;
24     for(j=1,p=1;p<n;j*=2,m=p){
25         for(p=0,i=n-j;i<n;i++) y[p++]=i;
26         for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
27         for(i=0;i<n;i++) wv[i]=x[y[i]];
28         for(i=0;i<m;i++) WS[i]=0;
29         for(i=0;i<n;i++) WS[wv[i]]++;
30         for(i=1;i<m;i++) WS[i]+=WS[i-1];
31         for(i=n-1;i>=0;i--) sa[--WS[wv[i]]]=y[i];
32         for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
33             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
34     }
35     return;
36 }
37 
38 int Rank[maxn],height[maxn];
39 
40 void calheight(int *r,int *sa,int n){
41     int i,j,k=0;
42     for(i=1;i<=n;i++) Rank[sa[i]]=i;
43     for(i=0;i<n;height[Rank[i++]]=k)
44         for(k?k--:0,j=sa[Rank[i]-1];r[i+k]==r[j+k];k++);
45     return;
46 }
47 
48 int r[maxn],sa[maxn];
49 char s[maxn];
50 
51 int ok(int k,int n){
52     int i,j,ret=0;
53     int maxx,minx;
54     maxx=-1;
55     minx=9999999;
56     for(i=1;i<=n;i++){
57         if(height[i]>=k)//分组满足大于k的
58         {
59             maxx=max(maxx,sa[i]);
60             minx=min(minx,sa[i]);
61         }
62         else
63         {
64             if(maxx-minx>=k)//之前满足条件就要+1;
65                 ret++;
66             maxx=sa[i];
67             minx=sa[i];
68         }
69     }
70     if(maxx-minx>=k)
71         ret++;
72     return ret;
73 }
74 
75 int main(){
76     int i,j;
77     while(cin>>s){
78         if(s[0]==#) break;
79         int len=strlen(s);
80         for(i=0;i<len;i++)
81             r[i]=s[i];
82         r[len]=0;
83         da(r,sa,len+1,123);
84         calheight(r,sa,len);
85         LL ans=0;
86         for(i=1;i<len;i++){
87             ans+=ok(i,len);
88         }
89         cout<<ans<<endl;
90     }
91     return 0;
92 }

 

以上是关于后缀数组的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段—— 数组的响应式方法

VSCode自定义代码片段10—— 数组的响应式方法

Sublime Text3自定义代码片段

后缀数组代码详解

●后缀数组○十三个例题

初学后缀数组记录(然而并不是很会。。&&很水。。)