后缀数组模板/LCP模板
//后缀数组模板,MANX为数组的大小
//支持的操作有计算后缀数组(sa数组), 计算相邻两元素的最长公共前缀(height数组),使用get_height();
//计算两个后缀a, 和b的最长公共前缀,请先使用lcp_init(),再调用get_lcp(a, b)得到
//下面的n是输入字符串的长度+1(n = strlen(s) + 1), m是模板的范围 m=128表示在字母,数字范围内,可以扩大也可缩小
//s[len] 是插入的一个比输入字符都要小的字符
struct SufArray {
char s[MAXN];
int sa[MAXN], t[MAXN], t2[MAXN], c[MAXN], n, m;
int rnk[MAXN], height[MAXN];//rnk和height数组
int mi[MAXN][], idxK[MAXN];//用于计算LCP void init() {
mem0(s);
mem0(height);
}
//读入字符串作为输入
void read_str() {
gets(s);
m = ;
n = strlen(s);
s[n++] = ' ';
}
void build_sa() {
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 - ];
dec (i, n - , ) sa[--c[x[i]]] = i;
for(int k = ; k <= n; k <<= ) {
int p = ;
rep (i, n - k, n - ) y[p++] = i;
rep (i, , n - ) if(sa[i] >= k) y[p++] = sa[i] - k;
rep (i, , m - ) c[i] = ;
rep (i, , n - ) c[x[y[i]]] ++;
rep (i, , m - ) c[i] += c[i - ];
dec (i, n - , ) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = ;
x[sa[]] = ;
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) break;
m = p;
}
}
void get_height() {
int k = ;
rep (i, , n - ) rnk[sa[i]] = i;
rep (i, , n - ) {
if(k) k --;
int j = sa[rnk[i] - ];
while(s[i + k] == s[j + k]) k ++;
height[rnk[i]] = k;
}
}
void rmq_init(int *a, int n) {
rep (i, , n - ) mi[i][] = a[i];
for(int j = ; ( << j) <= n; j ++) {
for(int i = ; i + (<<j) - < n; i ++) {
mi[i][j] = min(mi[i][j - ], mi[i + ( << (j - ))][j - ]);
}
}
rep (len, , n) {
idxK[len] = ;
while(( << (idxK[len] + )) <= len) idxK[len] ++;
}
}
int rmq_min(int l, int r) {
int len = r - l + , k = idxK[len];
return min(mi[l][k], mi[r - ( << k) + ][k]);
}
void lcp_init() {
get_height();
rmq_init(height, n);
}
int get_lcp(int a, int b) {
if(a == b) return n - a - ;
return rmq_min(min(rnk[a], rnk[b]) + , max(rnk[a], rnk[b]));
}
void solve() {
}
};
后缀数组模板/LCP模板的更多相关文章
- 洛谷P3809 后缀排序【后缀数组】【模板】
题目背景 这是一道模板题. 题目描述 读入一个长度为 nn 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编 ...
- 差异:后缀数组(wzz模板理解),单调栈
因为涉及到对模板的理解,所以就着代码看会好一些. 让那些坚决不颓代码的人受委屈了. 我是对着wzz的板子默写的,可能不完全一样啊. 还有代码注释里都是我个人的理解,不保证正确,但欢迎指正. 可以有选择 ...
- [TJOI2017]DNA --- 后缀数组
[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S, 有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个 ...
- 【后缀数组之SA数组】【真难懂啊】
基本上一搜后缀数组网上的模板都是<后缀数组——处理字符串的有力工具>这一篇的注释,O(nlogn)的复杂度确实很强大,但对于初次接触(比如窝)的人来说理解起来也着实有些困难(比如窝就活活好 ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
- 【BZOJ4453】cys就是要拿英魂! 后缀数组+单调栈+set
[BZOJ4453]cys就是要拿英魂! Description pps又开始dota视频直播了!一群每天被pps虐的蒟蒻决定学习pps的操作技术,他们把pps在这局放的技能记录了下来,每个技能用一个 ...
- BZOJ 3230 相似子串 ——后缀数组
题目的Source好有趣. 我们求出SA,然后求出每一个后缀中与前面本质不同的字符串的个数. 然后二分求出当前的字符串. 然后就是正反两次后缀数组求LCP的裸题了. 要注意,这时两个串的起点可能会相同 ...
- 【洛谷1117_BZOJ4650】[NOI2016] 优秀的拆分(哈希_后缀数组_RMQ)
题目: 洛谷1117 分析: 定义把我校某兔姓神犇Tzz和他的妹子拆分,为"优秀的拆分" 随便写个哈希就能有\(95\)分的好成绩-- 我的\(95\)分做法比fei较chang奇 ...
- BZOJ2119: 股市的预测(后缀数组)
Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工 具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长 ...
随机推荐
- C++(三十三) — 全局函数、成员函数的区别
区别: (1)全局函数的参数个数,比局部函数要多一个: (2)二者都可,返回元素.返回引用. class test { public: test(int a, int b) { this->a ...
- 1029: [JSOI2007]建筑抢修 贪心
https://www.lydsy.com/JudgeOnline/problem.php?id=1029 题意:n个建筑,每个有修复时间和爆炸时间,没有在爆炸时间内修复就会爆炸,问最多能修复的建筑 ...
- 转 Java对日期Date类进行加减运算一二三
请移步,https://blog.csdn.net/hacker_lees/article/details/74351838 ,感谢博主分享
- 原生javascript-日期年,月,日联动选择
在线例子:http://lgy.1zwq.com/dateSwitch/ 月份的判定,由于涉及到过多了判定条件,如果用if else会大大降低性能,建议用switch 语法 getDays:funct ...
- lspci能看到ifconfig -a看不到网卡
随着宽带技术的快速发展,服务器使用万兆网卡的概率越来越高.最近装了几台服务器都用的万兆网卡,为了图便宜,网卡和模块都是淘宝上买的,这部还真遇到不少问题. 我的服务器都是centos6.4 64位的,网 ...
- js自定义对象.属性 笔记
<一> js自定义对象 一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtabl ...
- List根据某个字段(属性)去重
有时候自带的list.Distinct()去重并不能满足魔门的要求,比如以下情况 如果testList的Name相同则视为重复,则可以如下实现,比写循环语句简洁多了 testList.Where((x ...
- Django-自定义分页组件
1.封装的分页代码: class PageInfo(object): def __init__(self,current_page,all_count,per_page,base_url,show_p ...
- python 获取当前时间(关于time()时间问题的重要补充)
python 获取当前时间 我有的时候写程序要用到当前时间,我就想用python去取当前的时间,虽然不是很难,但是老是忘记,用一次丢一次,为了能够更好的记住,我今天特意写下python 当前时间这 ...
- Linux 内核驱动自动创建设备节点并挂载设备
*注:本文来自http://blog.csdn.net/lwj103862095/article/details/17470573 一.首先需要在最开始定义两个数据结构: static struct ...