后缀数组(SA)学习记录】的更多相关文章

什么是后缀数组 后缀数组\(sa[i]\)表示字符串中字典序排名为\(i\)的后缀位置 \(rk[i]\)表示字符串中第\(i\)个后缀的字典序排名 举个例子: ababa a b a b a rk:3 5 2 4 1 sa: 5(a) 3(aba) 1(ababa) 4(ba) 2(baba) 那么就有\(sa[rk[i]]=rk[sa[i]]=i\) 后缀数组的求法 二周目 倍增法 看一会儿还是比较好记的 但没有理解每句话是在干什么的话以后再写就会没有思路 因此这里简述一下基本过程和一些关键…
参考资料:victorique的博客(有一点锅无伤大雅,记得看评论区),$wzz$ 课件(快去$ftp$%%%),$oi-wiki$以及某个人的帮助(万分感谢!) 首先还是要说一句:我不知道为什么我这么菜让我讲这么大神的知识点,我理解不深刻,你们可以随时$Ha(n)ck$然后我可能就fix不了了你知道吧 (好吧我大概又理解了因为数学是NC讲的数据结构是skyh讲的我能讲的可能也就是这种东西了) 希望还会的大神帮我解场...(某$bx$和某牛都$A$穿了) 顺便「无图预警」(懒得画又懒得粘) 当时…
后缀数组(SA)总结 这个东西鸽了好久了,今天补一下 概念 后缀数组\(SA\)是什么东西? 它是记录一个字符串每个后缀的字典序的数组 \(sa[i]\):表示排名为\(i\)的后缀是哪一个. \(rnk[i]\):可以理解为\(SA\)数组的逆,记录后缀\(i\)的排名是多少,\(rnk[SA[i]]=i\). \(lcp[i]\):别人一般叫\(height\),表示后缀\(SA[i]\)与\(SA[i-1]\)的最长公共前缀的长度. 后缀排序 求出后缀数组的算法,模板题 代码 先上代码,便…
bzoj3796Mushroom追妹纸 题目描述 Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他从网上找到了两篇极佳的情书,打算选择其中共同的部分.另外,Mushroom还有个一个情敌Ertanis,此人也写了封情书给妹子. Mushroom不希望自己的情书中完整的出现了情敌的情书.(这样抄袭的事情就暴露了). Mushroom把两封情书分别用字符串s1和s2来表示,Ertanis的情书用字符串…
参考资料这次是真抄的: 1.后缀数组详解 2.后缀数组-学习笔记 3.后缀数组--处理字符串的有力工具 定义 \(SA\)排名为\(i\)的后缀的位置 \(rk\)位置为\(i\)的后缀的排名 \(tp\)第二关键字的排名为\(i\)的后缀的位置,还被用作\(rank\)的暂存 \(tax\)每个排名对应的后缀数量 后缀数组就是为了求出\(sa\)和\(rk\) 性质 \(rk[sa[i]]=i\) \(sa[rk[i]]=i\) $LCP(x,y) $:字符串x与字符串y的最长公共前缀,在这里…
这篇博客不打算讲多么详细,网上关于后缀数组的blog比我讲的好多了,这一篇博客我是为自己加深印象写的. 给你们分享了那么多,容我自私一回吧~ 参考资料:这位dalao的blog 一.关于求SuffixArray的一些变量定义: 1. sa[i]=j,表示第i名的后缀从j开始 **存的是下标** 2. rnk[i]=j,从i开始的后缀是第j名的 **与sa为互逆运算,存的是值** 3. tp[i]=j, 第二关键字为i的后缀从j开始 **可理解为第二关键字的SA,存的是下标** 插入解释一下第一关…
后缀数组 概念 实际上就是将一个字符串的所有后缀按照字典序排序 得到了两个数组 \(sa[i]\) 和 \(rk[i]\),其中 \(sa[i]\) 表示排名为 i 的后缀,\(rk[i]\) 表示后缀 i 的排名 注意到 \(rk\) 和 \(sa\) 是互逆的,即 \(sa[rk[i]]=rk[sa[i]]=i\) 先讨论几个关于 \(lcp\) 的性质,令 \(lcp(i,j)\) 表示 \(sa[i]\) 和 \(sa[j]\) 的最长公共前缀 \(lcp(l,r)=min(lcp(l,…
题目链接 //输出ht见UOJ.35 #include<cstdio> #include<cstring> #include<algorithm> const int N=1e6+5; int n,tm[N],t1[N],t2[N],SA[N],rk[N],ht[N]; //SA[i]=j:排名为i的后缀开头的下标为j //rk[i]=j:以下标i开头的后缀排名为j //ht[i]:排名为i的后缀与排名为i-1的后缀的LCP长度 char s[N]; void Get_…
复杂度:O(nlogn) 注:从0到n-1 const int maxn=1e5; char s[maxn]; int sa[maxn],Rank[maxn],height[maxn],rmq[maxn][50]; void build() { //sa[] int n=strlen(s),m=128; static int x[maxn],y[maxn],c[maxn]; for(int i=0;i<m;++i)c[i]=0; for(int i=0;i<n;++i)c[x[i]=s[i]]…
真是一个三倍经验好题啊. 我们来观察这个题目,首先如果直接整体计算,怕是不太好计算. 首先,我们可以将每个子串都看成一个后缀的的前缀.那我们就可以考虑一个一个后缀来计算了. 为了方便起见,我们选择按照字典序来一次插入每个后缀,然后每次考虑当前后缀会产生的新串和与之前插入的串重复的串(这里之所以可以这么考虑,是因为如果他会对后面的串产生重复的话,那么会在后面那个串加入的时候计算的) 那么我们考虑,一个排名为\(i\)的后缀,插入之后不考虑重复的话,会新增多少个子串呢? 不难发现是\(n-sa[i]…