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. 第二百八十二节,MySQL数据库-MySQL视图

    MySQL数据库-MySQL视图 1.视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. 2.也 ...

  2. (转)关于三星cortex A9 Sate4412 开发板 uboot 启动的一些问题释疑

    说明:本文转载自:http://blog.csdn.net/gooogleman/article/details/17238079  作者:gooogleman                   日 ...

  3. 今天搞log4net插入错误日志去mysql数据库的时候出现了点问题,已解决。记录下解决方案

    先上图 配置log4net的时候要填这项,可是这个value我不知道啊.....上图里的value是我用下面的方法获取的 MySqlConnection con = new MySqlConnecti ...

  4. 新机器,分区为NTFS, 安装 Windows XP、Windows Server 2003 时蓝屏问题,修改为 FAT32 即可

    现象:安装刚刚开始就会蓝屏:Ghost版本的也无法正常开机. 原因:硬盘引起,通常是主板的RAID.或STAT的设置引起????? 最直接的原因是安装所在的分区的文件系统格式不正确,为NTFS 解决: ...

  5. CSS样式中” 大于号”

    CSS样式中” 大于号” 在一段CSS代码中见到一个大于号(>),代码如下: BODY#css-zen-garden > DIV#extraDiv2 { BACKGROUND-IMAGE: ...

  6. mysql中,查看当前数据库下所有的基表,不包括视图

    环境描述: mysql版本:5.5.57-log 操作系统版本:Red Hat Enterprise Linux Server release 6.6 (Santiago) 需求描述: 查看当前使用的 ...

  7. 打地鼠游戏iOS源代码项目

    打地鼠游戏源代码,游戏是一款多关卡基于cocos2d的iPad打地鼠游戏源代码.这也是一款高质量的打地鼠游戏源代码.能够拥有逐步上升的关卡的设置,大家能够在关卡时设置一些商业化的模式来盈利的,很完美的 ...

  8. 【RF库测试】Variable Should not Exist & variable should exist

    Variable Should not Exist variable should exist

  9. Centos安装Memcache

    Memcache概述 官方 Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据.简单的说就是将数据调用到内存中,然后从内存 ...

  10. Android 使用WebView显示网页

    构建WebView就可以显示Web信息.因为我觉得这里会讲述很多方式来实现WebView,所以我决定为每一种方式创建一个对应的Activity,MainActivity通过Button可以点击进入对应 ...