描述

后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围。在本题中,我们希望使用快排、Hash与二分实现一个简单的 O(n log^2⁡n ) 的后缀数组求法。详细地说,给定一个长度为 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+二分)相关推荐

  1. 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)

    题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...

  2. SPOJ 7258 SUBLEX 后缀数组_二分答案_前缀和

    SPOJ 7258 SUBLEX 后缀数组_二分答案_前缀和 Code: #include <cstdio> #include <algorithm> #include < ...

  3. FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解...

    Problem Description 最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课. 为了降低难度,免得所有人爆零.这里给几个提示的关键字 :字符串,回文,二分, ...

  4. [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)

    以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= = 定义(来自关于后缀数组的那篇国家集训队论文..) 后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列S ...

  5. poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)

    题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 可是大部分时间是在调试代码.由于模板的全局变量用混了,而自 ...

  6. 【后缀数组】【poj2774】【 Long Long Message】

    题意: 求两个串的最长连续子串. 我的想法: 枚举第二个串...在第一个串的后缀数组中二分查找. 复杂度NlogN.最坏情况N^2 题解: (3)height 数组:定义height[i]=suffi ...

  7. bzoj2946 [Poi2000]公共串(后缀数组 || 后缀自动机)

    bzoj2946 [Poi2000]公共串 原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2946 题意: 给出几个由小写字母构成的单词,求 ...

  8. 后缀数组水水水水水水题

    首先: jxrjxrjxr Orz,没有您我们都会死~ 然后就是我从jxr神犇那里借鉴(照抄)过来的后缀数组模板. #include<iostream> #include<cstdi ...

  9. Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens

    题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...

最新文章

  1. 完整代码+实操!手把手教你操作Faster R-CNN和Mask R-CNN
  2. 如何在JAVA代码中执行 exec master..xp_cmdshell @cmd // 当作SQL语句调用就成了 或者调用 Runtime.getRuntime().exec
  3. Tesorflow源代码安装方式以及错误的解决方法
  4. Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合
  5. 为什么要用python不用origin_Python告诉你为什么百度已死
  6. mybatis-plus大批量数据插入缓慢问题
  7. php js 比较,PHP与JS的比较
  8. pptv如何绑定邮箱账号
  9. 由ExecutorService及Callable実现有返回值的线程
  10. 通过pcm音频数据计算分贝
  11. 使用ffmpeg+opencv播放ts格式的视频
  12. 手机和我的私生活有什么必然的联系吗?
  13. kettle日志解析_Kettle运行日志记录
  14. 12生肖年份和星座组合图
  15. 《叶圣陶语文教育论集》的阅读笔记和读后感3400字
  16. 案例分享 | 数智化升级:红蜻蜓的转型之路(下)
  17. Python pip/pip3 常用命令
  18. windows7蓝牙怎么打开_【windows7】IP地址查询方法
  19. 单元测试cpp:Stub
  20. centos7 NFS客户端自动挂载

热门文章

  1. python【数据结构与算法】PriorityQueue and Huffuman树
  2. mysql1040_mysql Error 1040 too many connection解决办法
  3. redis stream java消息队列_Redis-消息队列的两种实现方式
  4. java bean join_spring data jpa 关联join查询出自定义实体java bean的坑
  5. Warning: Instance created by `useForm` is not connect to any Form element. Forget to pass `form` pro
  6. 上海网络推广浅析外链对网站优化的影响有多大?需要注意什么?
  7. 网络营销外包——网络营销外包专员浅析提升用户体验从哪入手?
  8. 网站建设很简单,想要成功却很难
  9. 商城网站前期功能设置这几项绝不能少!
  10. 如何增加新站前期收录几率?