tyvj1860后缀数组

Posted

tags:

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

描述

我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串。
后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])<suffix(sa[i+1]) 按照字典序方式比较
定义height[i]表示suffix(sa[i])与suffix(sa[i-1])之间的最长公共前缀长度,其中height[1]=0
你的任务就是求出SA和height这两个数组。字符串长度<=200000

输入格式

一行,为描述中的字符串(仅会出现小写字母)

输出格式

共两行,每行n个数,第一行为sa[i],第二行为height[i],其中每行的数均用空格隔开

测试样例1

输入

aabaaaab

输出

4 5 6 1 7 2 8 3 
0 3 2 3 1 2 0 1

后缀数组模板题
随便贴一个写得很丑的模板
以后要把它背下来啊啊啊
QAQ
技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 using namespace std;
 6 const int N=200050;
 7 int Sa[N],wu[N],wv[N],wa[N],wb[N],R[N],Rank[N],Height[N],rank[N];
 8 char s[N];
 9 int cmp(int *r,int a,int b,int l){return r[a]==r[b] && r[a+l]==r[b+l];}
10 inline void SA(int *r,int *sa,int n,int m){
11     int *x=wa,*y=wb;
12     for(int i=0;i<m;++i)wu[i]=0;
13     for(int i=0;i<n;++i)++wu[x[i]=r[i]];
14     for(int i=1;i<m;++i)wu[i]+=wu[i-1];
15     for(int i=n-1;i>=0;--i)sa[--wu[x[i]]]=i;
16     for(int j=1,p=0;p<n;j<<=1,m=p){
17         p=0;
18         for(int i=n-j;i<n;++i)y[p++]=i;
19         for(int i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
20         for(int i=0;i<m;++i)wu[i]=0;
21         for(int i=0;i<n;++i)++wu[wv[i]=x[y[i]]];
22         for(int i=0;i<m;++i)wu[i]+=wu[i-1];
23         for(int i=n-1;i>=0;--i)sa[--wu[wv[i]]]=y[i];
24         swap(x,y);
25         p=1;
26         x[sa[0]]=0;
27         for(int i=1;i<n;++i)x[sa[i]]=((y[sa[i]]==y[sa[i-1]]) && y[sa[i]+j]==y[sa[i-1]+j]) ? p-1 : p++;
28     }
29 }
30 inline void Get_Height(int *r,int n){
31     for(int i=1;i<=n;++i)rank[Sa[i]]=i;
32     for(int i=0,j=0,k=0;i<n;Height[rank[i++]]=k)
33         for(k?--k:0,j=Sa[rank[i]-1];r[i+k]==r[j+k];++k);
34 }
35 inline void output(int x){
36     if(!x)return;output(x/10);
37     putchar((x%10)+0);
38 }
39 int main(){
40     scanf("%s",s);
41     int len=strlen(s);
42     for(int i=0;i<len;++i)R[i]=s[i]-a+1;
43     R[len]=0;
44     SA(R,Sa,len+1,30);
45     Get_Height(R,len);
46     for(int i=1;i<=len;++i)output(Sa[i]+1),putchar( );puts("");
47     for(int i=1;i<=len;++i){
48         if(!Height[i])putchar(0);
49         else output(Height[i]);putchar( );
50     }puts("");
51     return 0;
52 }
tyvj1860

 

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

tyvj1860后缀数组

[TyvjP1515] 子串统计 [luoguP2408] 不同子串个数(后缀数组)

BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

tyvj1061移动服务——DP

tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

tyvj 1432 楼兰图腾