后缀数组

后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围。
在本题中,我们希望使用快排、Hash与二分实现一个简单的O(nlog2n)的后缀数组求法。
详细地说,给定一个长度为 n 的字符串S(下标 0~n-1),我们可以用整数 k(0≤k<n) 表示字符串S的后缀 S(k~n-1)。
把字符串S的所有后缀按照字典序排列,排名为 i 的后缀记为 SA[i]。
额外地,我们考虑排名为 i 的后缀与排名为 i-1 的后缀,把二者的最长公共前缀的长度记为 Height[i]。
我们的任务就是求出SA与Height这两个数组。

输入格式
输入一个字符串,其长度不超过30万。
字符串由小写字母构成。

输出格式
第一行为数组SA,相邻两个整数用1个空格隔开。
第二行为数组Height,相邻两个整数用1个空格隔开,我们规定Height[1]=0。

输入样例:
ponoiiipoi
输出样例:
9 4 5 6 2 8 3 1 7 0
0 1 2 1 0 0 2 1 0 2


说实话看到这道题的时候真的是一脸懵,这东西咋用hash,二分,快排。
后来找了些博客看,终于理解其中的思路了,
一、先记录整条的hash值。
二、用一个sort函数,自定义cmp。
三、通过二分确定两个后缀字符之间的前缀相同字母。

这道题写这篇题解的时候又重新去写了一遍,感觉真的难。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef unsigned long long ull;
const int base = 131;
const int N = 3e5 + 10;
char str[N];
ull h[N], p[N];
int sa[N], n;
ull gethash(int l, int r) {//得到某一段的hash值return h[r] - h[l - 1] * p[r - l + 1];
}
int sumsub(int a, int b) {int l = 0, r = min(n - a + 1, n - b + 1);//取最小的。while(l < r) {//二分。int mid = (l + r + 1) >> 1;if(gethash(a, a + mid - 1) != gethash(b, b + mid - 1))  r = mid - 1;else l = mid;}return r;
}
bool cmp(int a, int b) {int l = sumsub(a, b);//两个的相同前缀长度。int x = a + l > n ? - 1e9 : str[a + l];如果有一个单词都是前缀,防止发生数组越界。int y = b + l > n ? - 1e9 : str[b + l];return x < y;
}
int main() {scanf("%s", str + 1);//从第一个字符开始可以避免hash的边界问题。n = strlen(str + 1);p[0] = 1;for(int i = 1; i <= n; i++) {h[i] = h[i - 1] * base + str[i] - 'a' + 1;p[i] = p[i - 1] * base;sa[i] = i;}sort(sa + 1, sa + n + 1, cmp);//对下标进行排序。for(int i = 1; i <= n; i++) printf("%d%c", sa[i] - 1, i == n ? '\n' : ' ');printf("0 ");for(int i = 2; i <= n; i++)    printf("%d%c", sumsub(sa[i], sa[i - 1]), i == n ? '\n' : ' ');return 0;
}

这个算法耗时还是非常长的,并不是真正的能用的算法,但是这个写法的综合力度还是比较高的,思想还是可以借鉴的。

算法竞赛进阶指南——后缀数组相关推荐

  1. 中位数--《算法竞赛进阶指南》(货仓选址和七夕祭问题详解)

    中位数 今天又和大家见面了啦~ 依旧是 <算法竞赛进阶指南>的学习哦~ 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本.种群或概 ...

  2. 《算法竞赛进阶指南》打卡-基本算法-AcWing 93. 递归实现组合型枚举:递归与递推、dfs、状态压缩

    文章目录 题目解答 题目链接 题目解答 分析: 此题和笔者另一篇博文很像,只不过是限定了个数.<算法竞赛进阶指南>打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归.二进 ...

  3. 《算法竞赛进阶指南》数论篇

    <算法竞赛进阶指南>数论篇(1)-最大公约数,素数筛,欧拉函数,同余,欧拉定理,BSGS <算法竞赛进阶指南>数论篇(1)-最大公约数,素数筛,欧拉函数,同余,欧拉定理,BSG ...

  4. 《算法竞赛进阶指南(by 李煜东)》习题题解 集合

    又是笔者给自己挖的大坑. 这里是李煜东所著<算法竞赛进阶指南(by 李煜东)>的习题题解集合. 有任何错误请在对应文章下反馈或联系 nicest1919@163.com ,谢谢 qwq 从 ...

  5. CH5202 自然数拆分Lunatic版(算法竞赛进阶指南,完全背包)

    算法竞赛进阶指南,278页,完全背包 本题要点: 1.把完全背包的代码改改即可.常规的完全背包: 有n个物品,每个物品的体积是v[i], 价值是w[i], 求装到大小为m的大背包,能获得的最大价值(每 ...

  6. 金字塔(算法竞赛进阶指南)

    虽然探索金字塔是极其老套的剧情,但是有一队探险家还是到了某金字塔脚下. 经过多年的研究,科学家对这座金字塔的内部结构已经有所了解. 首先,金字塔由若干房间组成,房间之间连有通道. 如果把房间看作节点, ...

  7. AcWing 122. 糖果传递【贪心】【《算法竞赛进阶指南》,微软面试题 , HAOI2008】

    AcWing 122. 糖果传递 一.题目链接 二.题目分析 (一)算法标签 (二)解题思路 三.AC代码 四.其它题解 一.题目链接 AcWing 122. 糖果传递 进阶题目 AcWing 105 ...

  8. 算法竞赛进阶指南 骑士放置

    4: 最大独立集 :选出最多的点,使得选出的点之间没有边. 求最大独立集:选出最小的点可以破坏所有的边 <==>最小点覆盖 <==>最大匹配数. 假设最大匹配数为m,共有n个点 ...

  9. 算法竞赛进阶指南 萌新入门!

    算法竞赛进阶指南 文章目录 算法竞赛进阶指南 前言 一.介绍本书 二.如何阅读本书 三.总结 **笔记思路和结构 ** 算法竞赛进阶指南 这篇文章就简单的写一下吧! 前言 ​ 作为一个想要入坑的算法的 ...

最新文章

  1. 这几天研究了一下JDK14,发现它处理NPE的方式,真香!
  2. 常考数据结构和算法:跳台阶
  3. 如何设计通用的网站模板
  4. Linux账号和权限管理详解(超详细示例操作)!
  5. Nvidia Jetson TX2+Intel Realsense D435i跑ORB_SLAM3
  6. 批量添加后缀_掌握这 6 个批量处理技巧,少做 80% 的无用功!
  7. Pandas读取excel中的数据,并利用现有列数据生成新列
  8. uniapp实现签名板效果
  9. 下载XAMPP并安装和使用(Mac环境)
  10. metasploit中msf批量监测
  11. 黑莓9900 刷机体验(ROM:7.1.0.318_DoCoMo_Japan版)
  12. MySQL之Explain
  13. ios 截屏保存图片
  14. 产品沉思录精选:拒绝信息成瘾,重新思考你和信息的关系。
  15. 西电微机系统课程设计——步进电机开环控制系统设计
  16. python线程isalive_如何在线程类上使用.isAlive()
  17. 电子邮件营销中的邮件主题设计
  18. 计算机表格行列知识,计算机基础知识——应用表格.ppt
  19. Appium学习:雷电模拟器的使用
  20. linux内核设置mac地址,Linux下如何修改网卡MAC地址

热门文章

  1. python中html.parser_在Python中使用HTMLParser解析HTML的教程
  2. html三列布局源码,HTML三列布局 - 黄柳淞的个人页面 - OSCHINA - 中文开源技术交流社区...
  3. mysql的调试与分析_mysql日志管理分析调试实例_MySQL
  4. 怎么做图片文字二维码一起_怎么做?才能让文字编排更出彩
  5. inner join 和 exists 效率_一个in、exists、join的简单测试
  6. drawable文件怎么添加图片_怎么给PDF文件添加书签
  7. 2020年高考数学试题难吗?历史上最难数学卷不是2003!
  8. 大数据时代,数据科学都有些啥?
  9. 震撼!英伟达用深度学习做图像修复,毫无ps痕迹
  10. 视觉开发需要什么程度的数学_角度的概念在视觉上非常直观,但其数学定义并不是那么简单...