原题链接

后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者 DC3 算法实现,这超出了我们的讨论范围。

在本题中,我们希望使用快排、Hash 与二分实现一个简单的 O(nlog^2n) 的后缀数组求法。

详细地说,给定一个长度为 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

 题意:一个字符串长度为n,有n个后缀字符串([n,n],[n-1,n],[n-2,n],[n-3,n]……);

我们用id数组表示第i个后缀数组(i,n);

例如:abcd:id[4]=d,id[3]=cd,id[2]=bcd,id[1]=abcd;

要我们将这几个后缀字符串排序后输出当前字符串与前一个字符串的公共前缀和;

快排的话,排序需要O(n*logn),每次交换最坏都要匹配O(n),时间复杂度最坏为O(n^2*logn);

思路:哈希+二分

快排匹配的时候,匹配用二分查找公共前缀长度,每次匹配只需要O(logn),时间复杂度为O(n*logn^2);

哈希之前讲过,不会的可以看哈希例题

#include<iostream>
#include<algorithm>
#include<string.h>
#include<limits.h>
using namespace std;const int N = 3e6 + 10, base = 131;
typedef unsigned long long ULL;char str[N];//存储字符串
ULL h[N], p[N], id[N];//h存储哈希值,p表示进制次方,id[i]表示下标(i,n)后缀子串
int n;ULL get(int left, int right) {return h[right] - h[left - 1] * p[right - left + 1];//区间(l,r)哈希数值
}int mprifex(int a, int b) {//二分查找字符串(a,n)与(b,n)第一个不相等的字符距离a的位置,等价于公共子串长度;int l = 0, r = n-max(a,b)+1;while (l < r) {int mid = (l + r )/2;if (get(a, a + mid) != get(b, b + mid)) r = mid;//不相等表示之后都不mid之后都不向相等,,只需往前查找else l = mid+1;//相等表示当前及之前都相等,往后查询}return l ;
}bool cmp(int a, int b) {int l = mprifex(a, b);//l表示第一个不同的字符距离开头位置int av = a + l > n ? INT_MIN : str[a + l];//边界溢出肯定<没溢出的int bv = b + l > n ? INT_MIN : str[b + l];return av < bv;
}int main()
{scanf("%s", str + 1);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;//计算进制id[i] = i;//后缀下标=i}sort(id + 1, id + 1 + n, cmp);for (int i = 1; i <= n; ++i) {cout << id[i] - 1 << ' ';//输出从0到n-1;}cout << endl;for (int i = 1; i <= n; ++i)if (i == 1) cout << "0 ";else cout << mprifex(id[i - 1], id[i]) << ' ';//与前一个子串的最大公共前缀长度return 0;
}

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

  1. 算法竞赛进阶指南---0x14(Hash)后缀数组

    题面 题解 我们先来看朴素做法,对于一个长度为n的字符串,它的后缀也有n个,将他们排序(用快排)是 O(nlogn) ,如果是暴力比较两个字符串的字典序是 O(n) ,那么总的时间复杂度就是O(n2l ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. Mac OS X Terminal 101:终端使用初级教程
  2. Delphi Excel操作,写了个ADODataSet转Excel的函数作为后期学习的例子
  3. 使用JS实现2048小游戏
  4. POJ2019(二维RMQ问题 ST)
  5. python——前端常用的标签
  6. 集合——对象数组(引用数据类型数组)
  7. JAVA经典题--死锁案例
  8. U811.1接口EAI系列之二-BOM构成-委外BOM构成--VB语言
  9. linux组合键 发送指定信号_linux trap脚本信号捕获命令的使用
  10. 百度AI城市又搞事情!一天三场签约 上海市民要全面迎来AI了
  11. 房子怎么拆除_新规,可能拆除农村这4类房子,每户家庭可能获得40万
  12. AndroidStudio遇到的问题
  13. ASCII码不可见字符过滤处理
  14. 3dmax卸载工具_3Dmax软件无法安装?3Dmax软件正确卸载方法,重装无忧
  15. 【3dmax千千问】初学3dmax插件神器第15课|打开疯狂模渲大师已归档效果图的模型场景,弹窗提示“无法创建备份文件”报错,室内设计师应该怎么办?
  16. 电子签章安全用印方案:系统“三员分立”+印章“三权分立”
  17. VS2015 保护视力 背景色设置
  18. 联想计算机不识别硬盘分区,联想笔记本进PE不识别硬盘
  19. C#画布的创建和圆的画法
  20. 预推免面试准备 - C语言

热门文章

  1. Qt图例类QLegend详解
  2. 你会用“お”和“ご”吗?
  3. js高级程序设计(一) —— js简介
  4. Debian 为什么没有成立非营利基金会?
  5. Python期末总结
  6. 【项目笔记】布局文件报错Suspicious size: this will make the view invisible, probably intended for layout_width
  7. npm 淘宝镜像使用
  8. “碎片化时代”的灵动工作与生活
  9. 【保姆级】lookup-method标签实践与分析
  10. mysql连接不上数据库