1402 后缀数组 0x10「基本数据结构」例题

描述

后缀数组 (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,以此类推。

题意:

给一个字符串s的所有后缀按字典序排个序得到的就是后缀数组。求出排名第i的和排名第i-1的最长公共前缀长度,为height数组

思路:

依旧是Hash整个字符串,根据Hash值二分找到两个子串的最长公共子串,以此作为sort的比较依据

发现大佬们都是不用结构体的,写的很巧妙啊。

这种方法求后缀数组的复杂度是O(n(logn)^2)

 #include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f const int maxn = 3e5 + ;
char s[maxn];
unsigned long long H[maxn], p[maxn];
int sa[maxn], rk[maxn], height[maxn], n; unsigned long long getH(int i, int j)
{
return H[j] - H[i - ] * p[j - i + ];
} //二分求最长公共前缀长度
int lcp(int x, int y)
{
int l = , r = min(n - x + , n - y + );
while(l < r){
int mid = (l + r + ) / ;
if(getH(x, x + mid - ) == getH(y, y + mid - )){
l = mid;
}
else{
r = mid - ;
}
}
return l;
} bool cmp(int x, int y)
{
int l = lcp(x, y);
return s[x + l] < s[y + l];
} int main()
{
scanf("%s", s + );
n = strlen(s + );
p[] = ;
for(int i = ; i <= n; i++){
sa[i] = i;
H[i] = H[i - ] * + s[i] - 'a' + ;
p[i] = p[i - ] * ;
}
sort(sa + , sa + n + , cmp);
for(int i = ; i <= n; i++){
height[i] = lcp(sa[i - ], sa[i]);
}
for(int i = ; i <= n; i++){
printf("%d ", sa[i] - );
}
printf("\n");
for(int i = ; i <= n; i++){
printf("%d ", height[i]);
}
printf("\n"); return ;
}

CH1402 后缀数组【Hash】【字符串】【二分】的更多相关文章

  1. poj 3294 后缀数组 多字符串中不小于 k 个字符串中的最长子串

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16223   Accepted: 4763 Descr ...

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

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

  3. BZOJ3473:字符串(后缀数组,主席树,二分,ST表)

    Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...

  4. 后缀数组 hash求LCP BZOJ 4310: 跳蚤

    后缀数组的题博客里没放进去过..所以挖了一题写写 充实下博客 顺便留作板子.. 一个字符串S中 内容不同的子串 有 sigma{n-sa[i]+1-h[i]}   (噢 这里的h[]就是大家熟知的he ...

  5. 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分

    4310: 跳蚤 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 180  Solved: 83[Submit][Status][Discuss] De ...

  6. Uva12206 Stammering Aliens 后缀数组&&Hash

    Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...

  7. poj 3518 Corporate Identity 后缀数组->多字符串最长相同连续子串

    题目链接 题意:输入N(2 <= N <= 4000)个长度不超过200的字符串,输出字典序最小的最长公共连续子串; 思路:将所有的字符串中间加上分隔符,注:分隔符只需要和输入的字符不同, ...

  8. HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数. 可以用后缀数组来解决,复杂度O(n).先求出倍 ...

  9. POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串

    题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072 ...

随机推荐

  1. 第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型

    第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型 Hash操作,redis中Hash在内存中的存储格式如下图: hset(name, key, value)name ...

  2. DOM编程 学习笔记(二)

    学习内容: 1.document对象 2.event对象 该对象将标记型文档进行封装 该对象的作用,是对可标记型文档进行操作 常见操作,想要实现动态效果,需要对节点操作,那么先获取到这个节点,想获取节 ...

  3. 系统管理员应该知道的20条Linux命令

    如果您的应用程序不工作,或者您希望在寻找更多信息,这 20 个命令将派上用场. 在这个全新的工具和多样化的开发环境井喷的大环境下,任何开发者和工程师都有必要学习一些基本的系统管理命令.特定的命令和工具 ...

  4. 父div高度不能自适应子div高度的解决方案

    <div id="parent"><div id="content"> </div></div> 当conten ...

  5. Unity3d + PureMVC框架搭建

    0.流程:LoginView-SendNotification()---->LoginCommand--Execute()--->调用proxy中的函数操作模型数据--LoginProxy ...

  6. 使用jquery.uploadify动态传递自己的参数

    上传碰到这个问题在上传文件的时候同时上传文件的类型..上网找了半天.总于解决了..分享一下了..直接例子了.. html <%@ page language="java" i ...

  7. 帝国CMS 列表模板list.var支持程序代码

    1.增加模板时list.var模板需要勾选“使用程序代码”选项.如图: 2.直接添加PHP代码,不需要加<?和?>程序开始和结束标记. 3.字段值数组变量为$r,对应的字段变量为$r[字段 ...

  8. SSL 证书配置nginx

    ssl.conf文件: server { listen 443; server_name www.domain.com; # 改为绑定证书的域名 ssl on; ssl_certificate 1_w ...

  9. ios开发之--pop到指定页面

    1 推出到根视图控制器 [self.navigationController popToRootViewControllerAnimated:YES]; 2 推出到指定的视图控制器 for (UIVi ...

  10. linux安装nagios客户端

    ( 安装到 被监控的机器上)新增用户和组 useradd nagiosgroupadd nagcmd usermod -a -G nagcmd nagios (如果安装中报没有c编译器,就 yum i ...