后缀数组(SA)
学习了LRJ神犇的代码。orz。
首先真心建议了解下基数排序!!且要有一定的c++程序经验,否则程序很难看懂。
然后对着下面的程序调试(假装你已经会了算法思想)
弄个一个礼拜一下午就能学会了。
该算法基于倍增,然后错位比较,得到二元对并排序。
具体待更。
代码如下:
#include <bits/stdc++.h> using namespace std; #define re register #define rep(i, a, b) for (re int i = a; i <= b; ++i) #define repd(i, a, b) for (re int i = a; i >= b; --i) #define For(i, a, b, s) for (re int i = a; i <= b; s) #define maxx(a, b) a = max(a, b) #define minn(a, b) a = min(a, b) #define LL long long #define INF (1 << 30) inline int read() { , f = ; char c = getchar(); : f, c = getchar(); ) + (w << ) + (c ^ '), c = getchar(); return w * f; } ; char s[maxn]; int t[maxn], t2[maxn], sa[maxn], c[maxn], n; void build_sa(int m) { // m表示字符集大小 int *x = t, *y = t2; // 这样写是个技巧,可以快速交换数组(实际上交换了数组地址) rep(i, , m-) c[i] = ; rep(i, , n-) c[x[i] = s[i]]++; rep(i, , m-) c[i] += c[i-]; repd(i, n-, ) sa[--c[x[i]]] = i; // 到这完成了初始字符串的基数排序 ; k <= n; k <<= ) { ; rep(i, n-k, n-) y[p++] = i; rep(i, , n-) if (sa[i] >= k) y[p++] = sa[i]-k; //这两句完成了第二关键字的排序,而第二关键字为x[i]+k。 rep(i, , m-) c[i] = ; rep(i, , n-) c[x[y[i]]]++; rep(i, , m-) c[i] += c[i-]; repd(i, n-, ) sa[--c[x[y[i]]]] = y[i]; // 再完成第一关键字的排序 swap(x, y); // 交换数组,原来的y数组(对应后面的x)没有用了 p = ; x[sa[]] = ; // 根据原来的x数组(对应为y数组)修改现在的x数组 rep(i, , n-) x[sa[i]] = y[sa[i]] == y[sa[i-]] && y[sa[i]+k] == y[sa[i-]+k] ? p- : p++; if (p == n) return; // 如果所有数两两不同,到目前为止sa一定唯一不变了,退出 m = p; // 修改字符集大小 } } int main() { scanf("%s", s); n = strlen(s); build_sa((); rep(i, , n-) printf(); ; }
后缀数组(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 ...
- 后缀数组SA
复杂度:O(nlogn) 注:从0到n-1 const int maxn=1e5; char s[maxn]; int sa[maxn],Rank[maxn],height[maxn],rmq[max ...
- 洛谷2408不同字串个数/SPOJ 694/705 (后缀数组SA)
真是一个三倍经验好题啊. 我们来观察这个题目,首先如果直接整体计算,怕是不太好计算. 首先,我们可以将每个子串都看成一个后缀的的前缀.那我们就可以考虑一个一个后缀来计算了. 为了方便起见,我们选择按照 ...
- 洛谷4248 AHOI2013差异 (后缀数组SA+单调栈)
补博客! 首先我们观察题目中给的那个求\(ans\)的方法,其实前两项没什么用处,直接\(for\)一遍就求得了 for (int i=1;i<=n;i++) ans=ans+i*(n-1); ...
随机推荐
- Spring IOC MVC DI简单实现
目录的大致情况:所有的类都会加进来. 1.首先先写基本的Controller Service ServiceImpl Controller Service ServiceImpl是用来验证下面写的框架 ...
- [CUDA] 00 - GPU Driver Installation & Concurrency Programming
前言 对,这是一个高大上的技术,终于要做老崔当年做过的事情了,生活很传奇. 一.主流 GPU 编程接口 1. CUDA 是英伟达公司推出的,专门针对 N 卡进行 GPU 编程的接口.文档资料很齐全,几 ...
- selenium-04-验证码问题
对于web应用来说,大部分的系统在用户登录时都要求用户输入验证码,验证码的类型的很多,有字母数字的,有汉字的,甚至还要用户输入一条算术题的答案的,对于系统来说使用验证码可以有效果的防止采用机器猜测方法 ...
- selenium退出语句区别
selenium关闭窗口有两个方法,close与quit,我们稍作研究便知道这两个方法的区别. 1.看源码或API 这是close()的说明: Closes the current window. 关 ...
- DataFrame 转换为Dataset
写在前面: A DataFrame is a Dataset organized into named columns. A Dataset is a distributed collection o ...
- TypeScript中使用getElementXXX()
如果只是看解决方法,可以直接跳到第二小节 简述 Angular 1.x版本是用JavaScript编写的,我们在百度Angular经常会搜索到AngularJS,并不是JavaScript的什么衍生版 ...
- idea git和svn间切换
如图在file->settings->Version Controll间选择相对应的版本控制类型
- 【SQL server初级】SQL Server 2005 实现数据库同步备份 过程--结果---分析
数据库复制: 简单来说,数据库复制就是由两台服务器,主服务器和备份服务器,主服务器修改后,备份服务器自动修改. 复制的模式有两种:推送模式和请求模式,推送模式是主服务器修改后,自动发给备份服务器, ...
- 遇到不支持的 Oracle 数据类型 USERDEFINED
以前都是sql查询mdb空间数据没有什么问题,今天在用sql方式查询Oracle中的空间数据时候,出现错误.它不支持geometry.空间数据都带有shape属性.只要不查询shape字段就没问题.但 ...
- HDU 2044——一只小蜜蜂...(DP)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2044 题解 //递归思想,超时 #include<iostream> using namesp ...