后缀数组 学习笔记
1.后缀数组 学习笔记
2.Splay 学习笔记后缀数组 学习笔记
定义
我们定义后缀数组
求解后缀数组
首先
那么有一个利用倍增的思想求解后缀数组的
其实还有
Code
/*
* @Author: Ehundategh
* @Date: 2023-10-22 20:15:56
* @FilePath: \Code\Model\String\SA.cpp
* @Description: You Steal,I kill
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 2000010
using namespace std;
int Suffix_Array[MAXN],Rank[MAXN],n,k,Height[MAXN];
int Temp[MAXN];
char In[MAXN];
bool cmpsa(int i,int j){
if(Rank[i]!=Rank[j]){
return Rank[i]<Rank[j];
}
else{
int Secondi=i+k<=n?Rank[i+k]:-1;
int Secondj=j+k<=n?Rank[j+k]:-1;
return Secondi<Secondj;
}
}
void Get_SA(){
for(int i=1;i<=n;i++){
Suffix_Array[i]=i; Rank[i]=In[i];
}
for(k=1;k<=n;k*=2){
sort(Suffix_Array+1,Suffix_Array+n+1,cmpsa);
Temp[Suffix_Array[1]]=0;
for(int i=1;i<=n;i++){
Temp[Suffix_Array[i+1]]=Temp[Suffix_Array[i]]+(cmpsa(Suffix_Array[i],Suffix_Array[i+1])?1:0);
}
for(int i=1;i<=n;i++) Rank[i]=Temp[i];
}
return;
}
int main(){
scanf("%s",In+1);
n=strlen(In+1);
Get_SA();
for(int i=1;i<=n;i++) printf("%d ",Suffix_Array[i]);
}
这样就可以求出后缀数组了。
例题:
[[JSOI 2007]字符加密]([P4051 JSOI2007] 字符加密 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
思路
首先我们先把字符串复制一遍,那么将全新的字符串的后缀排序,从后缀排名从小到大遍历,如果出现后缀位置在原串中,就输出当前位置前一个位置的字符
高度数组
高度数组,后缀数组的神。
分为以下三个部分讲解:
- 定义
- 求解
- 例题
定义
首先我们先定义
我们定义:
举个例子,方便理解高度数组。
我们来看以下的字符串:
首先有
然后我们来求解
然后对于
对于
求解
求解有一个神奇的引理
关于这个引理的证明。详见2009国家队论文。
那么我们就可以通过这个引理,来实现
每次尝试与排名上一个的后缀比较,拓展得到当前的
代码
void Get_Height(){
for(int i=1,k=0;i<=n;i++){
if(Rank[i]==0)continue;
if(k>0) --k;
while(In[i+k]==In[Suffix_Array[Rank[i]-1]+k])++k;
Height[Rank[i]]=k;
}
}
例题
思路
高度数组模板题,对于每一个字符开头的后缀只需要每次统计总共的子串个数,然后再减去两两后缀的最长公共前缀去重即可。
思路
对于每一组询问,求Height的max即可。(话说这道题有一个加强版,要求出现k次,但是其实是一个做法,只需要求相邻k-1个的Height的max即可)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】