题面

题解

  1. 我们先来看朴素做法,对于一个长度为n的字符串,它的后缀也有n个,将他们排序(用快排)是 O(nlogn) ,如果是暴力比较两个字符串的字典序是 O(n) ,那么总的时间复杂度就是O(n2logn) ,显然不符合题中要求,那么如何做到题中所说的O(nlog2n) 呢?按题中思路来
  1. 我们的后缀数组用字符串下标表示 sa[i] 就表示下标 i到n的字符 例如sa[1]表示"ponoiiipoi" sa[10]表示"i"
    这样我们虽然在快排的时候无法优化,但是可以在比较两个字符串的时候可以优化,对于两个后缀字符串字串,例如 a=“ipoi” , b=“iiipoi” 我们先用二分来找出这两个字串的最大公共前缀,然后再比较公共前缀的后一位即可判断出哪个的字典序大 ,因为二分是O(logn),比较是O(1) ,所以可以优化为O(nlog2n)
  1. 二分的check函数怎么写,就是如何判断二分的值是不是最长公共前缀,因为我们的后缀串都是原串的字串,我们预先求出原串的hash值,然后就可以求出任意区间的hash值,那么对于两端区间,只要是hash值相等,那么我们就认为这两个字串相等,我们就可以用hash值是否相等来作为二分的条件

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<limits.h>using namespace std;
typedef unsigned long long ULL;
const int N = 3e5 + 10;
const int P = 131;int n;
char s[N];
ULL h[N], p[N];
int sa[N];//计算字串的hash值
ULL get(int l, int r) {return h[r] - h[l - 1] * p[r - l + 1];
}//二分找两个后缀串的最长公共前缀
int get_max_common_prefix(int a, int b) {int l = 0;int r = min(n - a + 1, n - b + 1);while (l < r) {int mid = (l + r + 1) >> 1;if (get(a, a + mid - 1) != get(b, b + mid - 1)) {r = mid - 1;} else {l = mid;}}return l;
}//比较两个后缀串的字典序
bool cmp(int a, int b) {int len = get_max_common_prefix(a, b);int va = a + len > n ? INT_MIN : s[a + len];int vb = b + len > n ? INT_MIN : s[b + len];return va < vb;
}int main() {scanf("%s", s + 1);n = strlen(s + 1);p[0] = 1;for (int i = 1; i <= n; i++) {h[i] = h[i - 1] * P + s[i];p[i] = p[i - 1] * P;sa[i] = i;}sort(sa + 1, sa + 1 + n, cmp);for (int i = 1; i <= n; i++) printf("%d ", sa[i] - 1);cout << endl;for (int i = 1; i <= n; i++) {if (i == 1) {printf("%d ", 0);} else {printf("%d ", get_max_common_prefix(sa[i - 1], sa[i]));}}return 0;
}

算法竞赛进阶指南---0x14(Hash)后缀数组相关推荐

  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. Java 性能调优的 11 个实用技巧
  2. 关于bhuman文件结构
  3. Java 8 - Stream流骚操作解读2_归约操作
  4. 《系统集成项目管理工程师》必背100个知识点-59项目总结会议
  5. 谈谈button标签和input标签的区别
  6. apache配置ssl证书
  7. linux /dev/null,Shell中 /dev/null和 /dev/null 21
  8. iOS 打电话 发短信功能的实现
  9. ANIMATION经典小车动画
  10. wps2019无法使用粘贴复制快捷键
  11. 抓取taobao的IP库
  12. 下一代IP协议----IPV6
  13. halcon裁剪图像_【Halcon】Halcon学习之七:改变图像的现实方式和大小
  14. 全力冲unreal了
  15. zookeeper启动报错:already running as process
  16. go-stat-reporter(1):golang开发通用报表展示系统,设计数据结构
  17. SNMP协议架构与操作类型
  18. 通过kiwix浏览wikipedia
  19. ipad和android平板应用程序,安卓平板相比iPad有哪些优势和劣势?
  20. C++设计并测试一个名为Rectangle的矩形类,其属性为矩形的左下角与右上角两个点的坐标,根据坐标能计算矩形的面积。

热门文章

  1. 计算机科学与技术在军中的应用,计算机科学技术在计算机教育的作用
  2. 第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题3题
  3. 图像算法原理与实践——图像修复之全变分模型
  4. 电动车跷跷板制作心得
  5. 用代码敲一番浪漫,Android开发音乐播放器
  6. 24个希腊符号的大小写、英文与中文的读音
  7. fwr171改无线服务器,【成功分享】WR702N硬改成WR703N
  8. 【java设计】:全民飞机大战小游戏制作
  9. mvc 路由 .html 404,部署ASP.NET的MVC网站到IIS 6.0中,发现路由无法解析而出现404错误解决方案...
  10. 波音737 MAX全球禁飞,外墙清洗行业安全同样不容小觑