http://uoj.ac/problem/35

模板题,重新理了一遍关系。看注释吧。充分理解了倍增的意义,翻倍之后对上一次排序的利用是通过一种类似于队列的方式完成的。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=;
const int pl=;
int sa[maxn+pl]={};//排名第i的是从sa[i]开始的数组
int rk[maxn+pl]={};//i的排名
int height[maxn+pl]={};//排名第i的与排名第i-1的最长相同前缀长度
int temp[maxn+pl]={};//暂时的排名
int cnt[maxn+pl]={};//第i种(字典序)前缀的有多少个(的前缀和)
int p[maxn+pl]={};//此次需要排列的sa的储存,处理了后缀长度不同的情况。
char ch[maxn+pl]={};
int siz;
bool equ(int x,int y,int l){ return rk[x]==rk[y]&&rk[x+l]==rk[y+l]; }
void SA(){
for(int i=;i<=siz;i++){rk[i]=ch[i];sa[i]=i;}
for(int i,sig=,l=,pos=;pos<siz;sig=pos){
pos=;
for(i=siz-l+;i<=siz;i++)p[++pos]=i;//根据上一次的sa决定p的储存顺序,没有排序则排在最前。
for(i=;i<=siz;i++) if(sa[i]>l) p[++pos]=sa[i]-l;//sa的计算是向字符串前端(左侧)拓展的
for(i=;i<=sig;i++) cnt[i]=;
for(i=;i<=siz;i++) cnt[rk[p[i]]]++;
for(i=;i<=sig;i++) cnt[i]+=cnt[i-];
for(i=siz;i>;i--) sa[cnt[rk[p[i]]]--]=p[i];//方便记忆板子的提示,只有这里是倒着扫的。
pos=;
for(i=;i<=siz;i++){
if(equ(sa[i],sa[i-],l))temp[sa[i]]=pos;
else temp[sa[i]]=++pos;
}
for(int i=;i<=siz;i++)rk[i]=temp[i];
if(!l)l=;
else l<<=;
}int j=;
for(int i=;i<=siz;i++){
if(rk[i]==){j=;continue;}
if(j)j--;
while(ch[i+j]==ch[sa[rk[i]-]+j]){
j++;
}height[rk[i]]=j;
}
}
int main(){
//freopen("a.in","r",stdin);
scanf("%s",ch+);siz=strlen(ch+);
SA();
for(int i=;i<=siz;i++)printf("%d ",sa[i]);
cout<<endl;
for(int i=;i<=siz;i++)printf("%d ",height[i]);
return ;
}

UOJ #35. 后缀排序 后缀数组 模板的更多相关文章

  1. 【UOJ #35】后缀排序 后缀数组模板

    http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ...

  2. UOJ #35. 后缀排序[后缀数组详细整理]

    #35. 后缀排序 统计 描述 提交 自定义测试 这是一道模板题. 读入一个长度为 nn 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符 ...

  3. Uoj #35. 后缀排序(后缀数组)

    35. 后缀排序 统计 描述 提交 自定义测试 这是一道模板题. 读入一个长度为 nn 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在 ...

  4. 洛谷.3809.[模板]后缀排序(后缀数组 倍增) & 学习笔记

    题目链接 //输出ht见UOJ.35 #include<cstdio> #include<cstring> #include<algorithm> const in ...

  5. Codevs 1500 后缀排序(后缀数组)

    1500 后缀排序 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 天凯是MIT的新生.Prof. HandsomeG给了他一个 ...

  6. UOJ.35.[模板]后缀排序(后缀数组 倍增)

    题目链接 论找到一个好的教程的正确性.. 后缀数组 下标从1编号: //299ms 2560kb #include <cstdio> #include <cstring> #i ...

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

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

  8. Luogu P3809 【模板】后缀排序(后缀数组板题)

    忘完了- emmm-

  9. luogu3809 后缀排序 后缀数组

    ref and 挑战程序设计竞赛. 主要是发现自己以前写得代码太难看而且忘光了,而且我字符串死活学不会啊,kmp这种东西我都觉得是省选+难度啊QAQ #include <iostream> ...

随机推荐

  1. 【BZOJ】1023: [SHOI2008]cactus仙人掌图 静态仙人掌(DFS树)

    [题意]给定仙人掌图(每条边至多在一个简单环上),求直径(最长的点对最短路径).n<=50000,m<=10^7. [算法]DFS树处理仙人掌 [题解]参考:仙人掌相关问题的处理方法(未完 ...

  2. 移动端meta声明

    <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --><html lang="zh-cmn-Hans"> ...

  3. kali2.0安装虚拟机工具

    kali2.0无法安装虚拟机工具,显示VMware Tools无法用于该虚拟机,或者安装之后无法进行复制.粘贴等操作. 解决办法: step1: 更换源 root@starnight:~# vim / ...

  4. UTF8字符串转换为汉字 c#

    using System; /// <summary> /// UTF8字符串转换为汉字用的类 /// 转换如"\\u8d35"之类的字符串为对应的汉字 /// < ...

  5. JSON.parse()——json字符串转JS

    JSON 通常用于与服务端交换数据. 在接收服务器数据时一般是字符串. 我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象. 语法 JSON.parse(text[, ...

  6. perl6正则 1: ~~ , //, m//, rx//

    ~~ perl6 中, 要匹配一个正则, 使用 ~~ 智能匹配符. > so 'abcde' ~~ /a.c/ True > so 'abcde' ~~ /a.d/ False > ...

  7. C++之 extern C的作用详解

    extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码.加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C+ ...

  8. 内存不够清理方法,costdown项目时如果裁剪不下来,也可以参考

    Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches 频繁的文件访问会导致系统的Cache使用量大增 $ free -m total used free shared ...

  9. 135.Candy---贪心

    题目链接 题目大意:分糖果,每个小朋友都有一个ratings值,且每个小朋友至少都要有一个糖果,而且每个小朋友的ratings值如果比左右邻舍的小朋友的ratings值高,则其糖果数量也比邻舍的小朋友 ...

  10. Java web项目中新建maven项目出现的问题

    1.首先新建maven项目,新建Maven时出现了版本问题,报错 第一个错误:jdk版本与project facets不匹配(大概是这样,忘记截图了),那么解决办法是: 在项目右击--->Pro ...