/*P1860 后缀数组
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述

我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串。
后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])<suffix(sa[i+1]) 按照字典序方式比较
定义height[i]表示suffix(sa[i])与suffix(sa[i-1])之间的最长公共前缀长度,其中height[1]=0
你的任务就是求出SA和height这两个数组。字符串长度<=200000
输入格式

一行,为描述中的字符串(仅会出现小写字母)
输出格式

共两行,每行n个数,第一行为sa[i],第二行为height[i],其中每行的数均用空格隔开
测试样例1

输入

aabaaaab
输出

4 5 6 1 7 2 8 3
0 3 2 3 1 2 0 1*/
//本题算法就是题目名,而且还是后缀数组最简单的应用。
//关于后缀数组我不想多说,推荐 算法合集之《后缀数组——处理字符串的有力工具》此h非我代码中的h。
//有时真想有人给我讲讲,自学是非常非常痛苦的。
//但有2个点超时,不过不管了。
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 200008
using namespace std;
int n,sa[2][N],rk[2][N],a[N],v[N],k,h[N];
char ch[N];
void geng(int sa[N],int rk[N],int SA[N],int RK[N])
{
for(int i=1;i<=n;i++)
v[rk[sa[i]]]=i;
for(int i=n;i;i--)
if(sa[i]>k)
SA[v[rk[sa[i]-k]]--]=sa[i]-k;
for(int i=n-k+1;i<=n;i++)
SA[v[rk[i]]--]=i;
for(int i=1;i<=n;i++)
RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+k]!=rk[SA[i-1]+k]);
return;
}
int main()
{
gets(ch+1);
n=strlen(ch+1);
for(int i=1;i<=n;i++)
a[i]=ch[i]-'a'+1;
int p=0,q=1;
for(int i=1;i<=n;i++)
v[a[i]]++;
for(int i=2;i<27;i++)
v[i]+=v[i-1];
for(int i=1;i<=n;i++)
sa[p][v[a[i]]--]=i;
for(int i=1;i<=n;i++)
rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
for(k=1;k<n;k<<=1)
{
geng(sa[p],rk[p],sa[q],rk[q]);
swap(p,q);
}
for(int i=1;i<=n;i++)
printf("%d ",sa[p][i]);
printf("\n");
k=0;
for(int i=1;i<=n;i++)
if(rk[p][i]==1)
h[1]=0;
else
{
int j=sa[p][rk[p][i]-1];
for(;a[i+k]==a[j+k];k++);
h[rk[p][i]]=k;
if(k>0)
k--;
}
for(int i=1;i<=n;i++)
printf("%d ",h[i]);
return 0;
}

后缀数组 TYVJ P1860 后缀数组的更多相关文章

  1. poj 2406 Power Strings (kmp 中 next 数组的应用||后缀数组)

    http://poj.org/problem?id=2406 Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submiss ...

  2. [UOJ#35] [UOJ后缀数组模板题] 后缀排序 [后缀数组模板]

    后缀数组,解决字符串问题的有利工具,本题代码为倍增SA算法 具体解释详见2009年国家集训队论文 #include <iostream> #include <algorithm> ...

  3. HDU - 6704 K-th occurrence (后缀数组+主席树/后缀自动机+线段树合并+倍增)

    题意:给你一个长度为n的字符串和m组询问,每组询问给出l,r,k,求s[l,r]的第k次出现的左端点. 解法一: 求出后缀数组,按照排名建主席树,对于每组询问二分或倍增找出主席树上所对应的的左右端点, ...

  4. C++语言中数组指针和指针数组彻底分析

    #################################                              ##       基本知识               ##        ...

  5. php将对象数组转成普通数组

    不知道为什么,把数组序列化为json,然后存到redis(string类型).然后再取出来反序列化为数组,就变成对象数组了 thinkPHP普通数组取值$arr['key'] 对象数组取值$arr-& ...

  6. C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用

    类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...

  7. 窥探Swift之数组安全索引与数组切片

    今天是元宵节,祝大家元宵节快乐!在Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值.在使用数组时,一个常见的致命错误就是数组越界.如果在 ...

  8. 求一个数组的最大子数组(C/C++实现)

    最大子数组:要求相连,加起来的和最大的子数组就是一个数组的最大子数组.编译环境:VS2012,顺便说句其实我是C#程序员,我只是喜欢学C++. 其实这是个半成品,还有些BUG在里面,不过总体的思路是这 ...

  9. JavaScript 数组 length 属性获取数组长度或设置数组元素的数目

    JavaScript 数组 length 属性 JavaScript 数组 length 属性可返回或设置或组中元素的数目,语法如下: array_object.length 利用 length 属性 ...

随机推荐

  1. 【Leetcode】746. Min Cost Climbing Stairs

    题目地址: https://leetcode.com/problems/min-cost-climbing-stairs/description/ 解题思路: 官方给出的做法是倒着来,其实正着来也可以 ...

  2. hdu1501 记忆化搜索。。。

    Problem Description Given three strings, you are to determine whether the third string can be formed ...

  3. 元素的colspan和rowspan

    colspan和rowspan这两个属性用于创建特殊的表格. colspan用来指定单元格横向跨越的列数:colspan就是合并列的,colspan=2就是合并两列. rowspan用来指定单元格纵向 ...

  4. 2.MVC基础-Model概述(思维导图)

    已思维导图形式,便于记忆和补充

  5. 从 ASP.NET Core 2.1 迁移到 2.2 踩坑总结

    官方迁移文档:https://docs.microsoft.com/zh-cn/aspnet/core/migration/21-to-22?view=aspnetcore-2.2&tabs= ...

  6. js入门之DOM

    一.理解Web API Web API Application Programming Interface 应用程序编程接口, 是一个预先定义好的函数和方法 目的是提供应用程序与开发人员基于某软件或硬 ...

  7. Java 之 IO 异常的处理【了解】

    一.JDK7 前的处理 前面的 Demo 中,一直把异常抛出,而在实际中并不能这样处理,建议使用 try...catch...finally 代码块,处理异常部分. 格式: try{ 可能会产出异常的 ...

  8. c# 字段成员

  9. Vue中的button事件

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. java相关网址汇总2

    分享几个高质量的技术博客和网站. 一.博客 0.酷壳 - COOLSHELL 博客地址是 https://coolshell.cn/. 这个博客的作者是技术圈基本无人不知的技术大牛,江湖人称耗子叔,网 ...