[sa][后缀数组]关于后缀数组的若干技巧
来源:互联网 发布:软件项目进展汇报 编辑:程序博客网 时间:2024/05/11 18:25
简单入门
sa[i]表示将后缀从小到大排名后,第i小的后缀的位置
rank[i]表示i这个后缀的排名
height[i]表示sa[i]和sa[i-1]的lcp
lcp(i,j)表示sa[i]和sa[j]的lcp。则lcp(i,j)=min(height[i+1],……,height[j]).
求后缀数组的原理:
将每次我们求的后缀的长度*2,求这个长度的后缀的排名。则求这次的后缀的排名时可以使用以前的信息。如求位置为i,长度为j*2的后缀的排名,则可以通过比较位置i,长度为j的后缀(第一关键字)和位置i+j,长度为j的后缀(第二关键字)的排名(上一次长度的信息)来得到i位置长度为j的后缀的排名。
求后缀数组的方法:
那么如果求每个后缀时都直接保存上次的信息,然后快排,则效率为nlog^2n.使用基数排序的技巧来优化,使得效率达到nlogn。
记w[i]表示第一关键字排名为i的后缀数量,然后做一遍前缀和的值。即所有第一关键字为i时第二关键字最大时的后缀的排名。
x[i]表示上一轮排名后,i的排名。
暂时的rank[i]表示第二关键字排名第i小的第一关键字的位置。
则我们将第二关键字倒序枚举,即从大到小枚举第二关键字,对于第一关键字相等的后缀,第二关键字大的分配到的排名应该越大,即sa[w[rank[i]]–]=rank[i]。
给出样例:
对于基排我们有
10,11,12,13,先将十位个位分开丢进桶
1:0 1 2 3
则13分配到的排名应该尽量大,即sa[x]=(13的位置)和sa[y]=(12的位置),x>y。
后缀数组中的实现为,先枚举到第二关键字大的3,然后rank[]得到其第一关键字为1,w表示1这个桶中最大的那个数被取出时的排名,实现了13的排名取值。
给出模板:
inline void Sa(){ int m=127,u,v; for(int i=1;i<=m;++i) w[i]=0; for(int i=1;i<=n;++i) w[x[i]=sr[i]]++; for(int i=1;i<=m;++i) w[i]+=w[i-1]; for(int i=n;i>=1;--i) sa[w[x[i]]--]=i; for(int j=1;j<=n;j*=2) { int cnt=0; for(int i=n-j+1;i<=n;++i) rank[++cnt]=i; for(int i=1;i<=n;++i) if(sa[i]>j) rank[++cnt]=sa[i]-j; for(int i=1;i<=m;++i) w[i]=0; for(int i=1;i<=n;++i) w[x[i]]++; for(int i=1;i<=m;++i) w[i]+=w[i-1]; for(int i=n;i>=1;--i) sa[w[x[rank[i]]]--]=rank[i]; m=0; for(int i=1;i<=n;++i) { u=sa[i];v=sa[i-1]; if(x[u]!=x[v]||x[u+j]!=x[v+j]) ++m; rank[u]=m; } if(m==n) break; for(int i=1;i<=n;++i) x[i]=rank[i]; } int j=0; for(int i=1;i<=n;++i) { v=sa[rank[i]-1]; j=max(0,j-1); while(sr[i+j]==sr[v+j]) ++j; hei[rank[i]]=j; }}
若干技巧(持续更新,有待发现
很多题不好做就先二分再想想怎么check
本质不同的子串个数为:
- [sa][后缀数组]关于后缀数组的若干技巧
- 后缀数组(SA)
- SA后缀数组模板
- 后缀数组SA
- 关于后缀数组的SA和Rank说明
- 后缀数组练习题若干
- 后缀数组练习题若干
- 后缀数组(SA)模版
- 【后缀数组sa学习小记】
- 后缀数组求rank数组,sa数组
- 后缀数组的构造sa,rank和height数组
- 【后缀数组】关于后缀数组模板的注解
- 【后缀数组】关于后缀数组模板的注解续
- poj3581 Sequence(后缀数组sa的运用+离散化)
- 关于后缀数组
- 后缀数组(SA倍增算法)
- SA后缀数组模板 文件修复
- Hdu-5769 Substring (SA后缀数组)
- HDU-2102-A计划
- C++基础-文件
- 修改主机名(/etc/hostname和/etc/hosts区别)
- linux C读书笔记
- Spring Transaction属性之Propagation
- [sa][后缀数组]关于后缀数组的若干技巧
- static 注意事项
- HDU2009 C语言
- 机器学习实战_04-贝叶斯
- 菜鸟先飞之jAVA_面向对象特征
- Spring复习笔记
- java中的控制流语句
- C++基础-多态
- 电脑软键盘效果