后缀数组SA
复杂度: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]]++;
for(int i=1;i<m;++i)c[i]=c[i]+c[i-1];
for(int i=n-1;i>=0;--i)sa[--c[x[i]]]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=n-k;i<n;++i)y[p++]=i;
for(int i=0;i<n;++i)if(sa[i]>=k)y[p++]=sa[i]-k;
for(int i=0;i<m;++i)c[i]=0;
for(int i=0;i<n;++i)c[x[y[i]]]++;
for(int i=1;i<m;++i)c[i]+=c[i-1];
for(int i=n-1;i>=0;--i)sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1;x[sa[0]]=0;
for(int i=1;i<n;++i)x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n)break;
m=p;
}
//Rank[]
for(int i=0;i<n;++i)Rank[sa[i]]=i;
//height[]
int len=0;
for(int i=0;i<n;++i)
{
if(len)len--;
if(Rank[i]==0)continue;
int j=sa[Rank[i]-1];
while(s[i+len]==s[j+len])len++;
height[Rank[i]]=len;
}
//rmq[][]
for(int i=1;i<n;++i)rmq[i][0]=height[i];
for(int i=1;(1<<i)<n;++i)for(int j=1;j+(1<<i)<=n;++j)rmq[j][i]=min(rmq[j][i-1],rmq[j+(1<<(i-1))][i-1]);
}
int lcp(int a,int b)//a,b为两后缀的字典序排名
{
if(a==b)return strlen(s+sa[a]);
if(a>b)swap(a,b);
int k=0;
while((1<<(k+1))<=b-a)k++;
return min(rmq[a+1][k],rmq[b-(1<<k)+1][k]);
}
后缀数组SA的更多相关文章
- 后缀数组(SA)总结
后缀数组(SA)总结 这个东西鸽了好久了,今天补一下 概念 后缀数组\(SA\)是什么东西? 它是记录一个字符串每个后缀的字典序的数组 \(sa[i]\):表示排名为\(i\)的后缀是哪一个. \(r ...
- 后缀数组SA学习笔记
什么是后缀数组 后缀数组\(sa[i]\)表示字符串中字典序排名为\(i\)的后缀位置 \(rk[i]\)表示字符串中第\(i\)个后缀的字典序排名 举个例子: ababa a b a b a rk: ...
- 后缀数组SA入门(史上最晦涩难懂的讲解)
参考资料:victorique的博客(有一点锅无伤大雅,记得看评论区),$wzz$ 课件(快去$ftp$%%%),$oi-wiki$以及某个人的帮助(万分感谢!) 首先还是要说一句:我不知道为什么我这 ...
- bzoj3796(后缀数组)(SA四连)
bzoj3796Mushroom追妹纸 题目描述 Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他从 ...
- [笔记]后缀数组SA
参考资料这次是真抄的: 1.后缀数组详解 2.后缀数组-学习笔记 3.后缀数组--处理字符串的有力工具 定义 \(SA\)排名为\(i\)的后缀的位置 \(rk\)位置为\(i\)的后缀的排名 \(t ...
- 【字符串】后缀数组SA
后缀数组 概念 实际上就是将一个字符串的所有后缀按照字典序排序 得到了两个数组 \(sa[i]\) 和 \(rk[i]\),其中 \(sa[i]\) 表示排名为 i 的后缀,\(rk[i]\) 表示后 ...
- 浅谈后缀数组SA
这篇博客不打算讲多么详细,网上关于后缀数组的blog比我讲的好多了,这一篇博客我是为自己加深印象写的. 给你们分享了那么多,容我自私一回吧~ 参考资料:这位dalao的blog 一.关于求Suffix ...
- 洛谷2408不同字串个数/SPOJ 694/705 (后缀数组SA)
真是一个三倍经验好题啊. 我们来观察这个题目,首先如果直接整体计算,怕是不太好计算. 首先,我们可以将每个子串都看成一个后缀的的前缀.那我们就可以考虑一个一个后缀来计算了. 为了方便起见,我们选择按照 ...
- 洛谷4248 AHOI2013差异 (后缀数组SA+单调栈)
补博客! 首先我们观察题目中给的那个求\(ans\)的方法,其实前两项没什么用处,直接\(for\)一遍就求得了 for (int i=1;i<=n;i++) ans=ans+i*(n-1); ...
随机推荐
- vue-cli3引入svg图标全过程以及遇到的坑
https://blog.csdn.net/weixin_41229588/article/details/101159755 一.配置 1.安装依赖: npm install svg-sprite- ...
- Spring Web Flow 笔记
在Spring 中配置 Web Flow <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...
- 【C++】VS2017 不能将const char * 分配给 char *
我的方式是把结构体中定义的 char * 换成string #include <iostream> #include<string> using namespace std; ...
- PHP获取所有扩展及扩展下的所有函数签名生成php.snippet
<?php $ext_info = array(); $modules = get_loaded_extensions(); foreach ($modules as $module) { $f ...
- Java中如何通过try优雅地释放资源?
时间紧迫,长话短说,今天,小明给大家同步一个知识点,使用try-with-resources来优雅地关闭资源. 1. 背景 其实,在JDK 7就已经引入了对try-with-resources的支持, ...
- CVPR 2020论文收藏(转知乎:https://zhuanlan.zhihu.com/p/112337176)
CVPR 2020 共收录 1470篇文章,根据当前的公布情况,人工智能学社整理了以下约100篇,分享给读者. 代码开源情况:详见每篇注释,当前共15篇开源.(持续更新中,可关注了解). 算法主要领域 ...
- json格式的文件操作
1.字典转换为字符串(json.dumps) jsongeshi={"name":"yajuan","age":"10" ...
- 中阶 d06.1 cookie && session && jsp介绍
##Cookie > 饼干. 其实是一份小数据, 是服务器给客户端,并且存储在客户端上的一份小数据 ### 应用场景 > 自动登录.浏览记录.购物车. ###为什么要有这个Cookie & ...
- Spring Cloud和eureka启动报错 解决版本依赖关系
导读 An attempt was made to call a method that does not exist. The attempt was made from the following ...
- AJ学IOS(54)多线程网络之NSOperation重要知识
AJ分享,必须精品 一:队列的类型与队列添加任务 1: 主队列 [NSOperationQueue mainQueue] 添加到”主队列”中的操作,都会放到主线程中执行. 2:非主队列 [[NSOpe ...