1402 后缀数组 (hash+二分)
描述
后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围。在本题中,我们希望使用快排、Hash与二分实现一个简单的 O(n log^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这两个数组。<n) i="" i-1="" p="">
输入格式
一个字符串,长度不超过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
样例解释
排名第一(最小)的后缀是9(S[9~9],即字符串 i),第二的是后缀4(S[4~9],即字符串iiipoi),第三的是后缀5(S[5~9],即字符串iipoi)以此类推。Height[2]表示排名第2与第1的后缀的最长公共前缀,长度为1,Height[3]表示排名第3与第2的后缀的最长公共前缀,长度为2,以此类推。
思路:因为要按照字典序排序,既然排序,那么就想到了快排sort。
那就要自定义比较函数,如果对于两个字符串O(n)扫描比较,那么总体复杂度O(n2logn)
我们可以二分比较的长度,对于同样长的字符串通过对字符串hash得到的hash值比较其是否相同,O(logn)找出其不同位置,然后比较该位置大小,这样复杂度O(nlog2n)
#include<bits/stdc++.h> using namespace std;const int maxn = 1000005; unsigned long long f[maxn],p[maxn]; char word[maxn]; int n; struct Node {int pos;int hei;Node(int x = 0,int h=0):pos(x),hei(h) {} } node[maxn];unsigned long long getf(int l,int r) {return f[r] - f[l-1]*p[r-l+1]; }int cal(Node a,Node b) {int lena = n - a.pos + 1;int lenb = n - b.pos + 1;int l = 1,r = min(lena,lenb);while(l <= r){int mid = (l+r)>>1;if(getf(a.pos,a.pos+mid-1) == getf(b.pos,b.pos+mid-1)){l = mid + 1;}else{r = mid - 1;}}return l-1; } bool cmp(Node a,Node b) {int t = cal(a,b);return word[a.pos+t] < word[b.pos+t]; } int main() {scanf("%s",word+1);n = strlen(word+1);p[0] = 1;f[0] = 0;for(int i=1; i<=n; i++){node[i].pos = i;f[i] = f[i-1] * 131 + word[i] - 'a' + 1;p[i] = p[i-1]*131;}sort(node+1,node+1+n,cmp);for(int i=2; i<=n; i++){node[i].hei = cal(node[i-1],node[i]);}for(int i=1; i<=n; i++){printf("%d",node[i].pos-1);if(i != n)printf(" ");elseprintf("\n");}for(int i=1; i<=n; i++){printf("%d",node[i].hei);if(i != n)printf(" ");elseprintf("\n");} }
View Code
转载于:https://www.cnblogs.com/iwannabe/p/10653581.html
1402 后缀数组 (hash+二分)相关推荐
- 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)
题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...
- SPOJ 7258 SUBLEX 后缀数组_二分答案_前缀和
SPOJ 7258 SUBLEX 后缀数组_二分答案_前缀和 Code: #include <cstdio> #include <algorithm> #include < ...
- FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解...
Problem Description 最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课. 为了降低难度,免得所有人爆零.这里给几个提示的关键字 :字符串,回文,二分, ...
- [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)
以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= = 定义(来自关于后缀数组的那篇国家集训队论文..) 后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列S ...
- poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)
题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 可是大部分时间是在调试代码.由于模板的全局变量用混了,而自 ...
- 【后缀数组】【poj2774】【 Long Long Message】
题意: 求两个串的最长连续子串. 我的想法: 枚举第二个串...在第一个串的后缀数组中二分查找. 复杂度NlogN.最坏情况N^2 题解: (3)height 数组:定义height[i]=suffi ...
- bzoj2946 [Poi2000]公共串(后缀数组 || 后缀自动机)
bzoj2946 [Poi2000]公共串 原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2946 题意: 给出几个由小写字母构成的单词,求 ...
- 后缀数组水水水水水水题
首先: jxrjxrjxr Orz,没有您我们都会死~ 然后就是我从jxr神犇那里借鉴(照抄)过来的后缀数组模板. #include<iostream> #include<cstdi ...
- Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens
题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...
最新文章
- 完整代码+实操!手把手教你操作Faster R-CNN和Mask R-CNN
- 如何在JAVA代码中执行 exec master..xp_cmdshell @cmd // 当作SQL语句调用就成了 或者调用 Runtime.getRuntime().exec
- Tesorflow源代码安装方式以及错误的解决方法
- Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合
- 为什么要用python不用origin_Python告诉你为什么百度已死
- mybatis-plus大批量数据插入缓慢问题
- php js 比较,PHP与JS的比较
- pptv如何绑定邮箱账号
- 由ExecutorService及Callable実现有返回值的线程
- 通过pcm音频数据计算分贝
- 使用ffmpeg+opencv播放ts格式的视频
- 手机和我的私生活有什么必然的联系吗?
- kettle日志解析_Kettle运行日志记录
- 12生肖年份和星座组合图
- 《叶圣陶语文教育论集》的阅读笔记和读后感3400字
- 案例分享 | 数智化升级:红蜻蜓的转型之路(下)
- Python pip/pip3 常用命令
- windows7蓝牙怎么打开_【windows7】IP地址查询方法
- 单元测试cpp:Stub
- centos7 NFS客户端自动挂载
热门文章
- python【数据结构与算法】PriorityQueue and Huffuman树
- mysql1040_mysql Error 1040 too many connection解决办法
- redis stream java消息队列_Redis-消息队列的两种实现方式
- java bean join_spring data jpa 关联join查询出自定义实体java bean的坑
- Warning: Instance created by `useForm` is not connect to any Form element. Forget to pass `form` pro
- 上海网络推广浅析外链对网站优化的影响有多大?需要注意什么?
- 网络营销外包——网络营销外包专员浅析提升用户体验从哪入手?
- 网站建设很简单,想要成功却很难
- 商城网站前期功能设置这几项绝不能少!
- 如何增加新站前期收录几率?