后缀排序(codevs 1500)
天凯是MIT的新生。Prof. HandsomeG给了他一个长度为n的由小写字母构成的字符串,要求他把该字符串的n个后缀(suffix)从小到大排序。
何谓后缀?假设字符串是S=S1S2……Sn,定义Ti=SiSi+1……Sn。T1, T2, …, Tn就叫做S的n个后缀。
关于字符串大小的比较定义如下(比较规则和PASCAL中的定义完全相同,熟悉PASCAL的同学可以跳过此段):
若A是B的前缀,则A<B;否则令p满足:A1A2…Ap-1=B1B2…Bp-1,Ap<>Bp。如果Ap<Bp,则A<B;否则A>B。
第一行一个整数n(n<=15000)
第二行是一个长度为n字串。
输出文件包含n行,第i行是一个整数pi。表示所有的后缀从小到大排序后是Tp1, Tp2, …, Tpn。
4
abab
3
1
4
2
说明:后缀排序后的顺序是T3=”ab”, T1=”abab”, T4=”b”, T2=”bab”。所以输出是3, 1, 4, 2。
/*后缀数组裸题*/
#include<cstdio>
#include<iostream>
#define N 15010
using namespace std;
int n,m=,s[N],sa[N],t1[N],t2[N],c[N];
bool cmp(int *y,int a,int b,int k){
int a1=y[a],b1=y[b];
int a2=a+k>=n?-:y[a+k];
int b2=b+k>=n?-:y[b+k];
return a1==b1&&a2==b2;
}
void DA(){
int *x=t1,*y=t2;
for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[i]=s[i]]++;
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;~i;i--) sa[--c[x[i]]]=i;
for(int k=,p=;k<=n;k*=,m=p,p=){
for(int i=n-k;i<n;i++) y[p++]=i;
for(int i=;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[y[i]]]++;
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;~i;i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);p=;x[sa[]]=;
for(int i=;i<n;i++)
if(cmp(y,sa[i-],sa[i],k)) x[sa[i]]=p-;
else x[sa[i]]=p++;
if(p>=n) break;
}
}
int main(){
char ch[N];
scanf("%d%s",&n,ch);
for(int i=;i<n;i++)
s[i]=ch[i];
DA();for(int i=;i<n;i++)printf("%d ",sa[i]+);
return ;
}
后缀排序(codevs 1500)的更多相关文章
- codevs 1500 后缀排序
codevs 1500 后缀排序 http://codevs.cn/problem/1500/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 天凯是MI ...
- Codevs 1500 后缀排序(后缀数组)
1500 后缀排序 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 天凯是MIT的新生.Prof. HandsomeG给了他一个 ...
- codevs1500 后缀排序
题目描述 Description 天凯是MIT的新生.Prof. HandsomeG给了他一个长度为n的由小写字母构成的字符串,要求他把该字符串的n个后缀(suffix)从小到大排序. 何谓后缀?假设 ...
- UOJ#35 后缀排序
这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编号为 1 到 n. 除此之外为 ...
- P3809 【模板】后缀排序
P3809 [模板]后缀排序 从这学的 后缀数组sa[i]就表示排名为i的后缀的起始位置 x[i]是第i个元素的第一关键字 y[i]表示第二关键字排名为i的数,在第一关键字中的位置 #include& ...
- LG3809 【模板】后缀排序
题意 题目背景 这是一道模板题. 题目描述 读入一个长度为 $ n $ 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的 ...
- 2018.11.24 loj#111. 后缀排序(后缀数组)
传送门 后缀排序模板题. 终于会后缀数组了(然而只会倍增并不会DC3DC3DC3). 在这里列举几个数组的意思: sai:sa_i:sai:当前排名第iii的后缀的起始下标. rkirk_irki ...
- uoj35 后缀排序
题目链接:http://uoj.ac/problem/35 这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第 ...
- 洛谷:P3809 【模板】后缀排序(后缀数组模板)
P3809 [模板]后缀排序 题目链接:https://www.luogu.org/problemnew/show/P3809 题目背景 这是一道模板题. 题目描述 读入一个长度为 nn 的由大小写英 ...
随机推荐
- ES-自然语言处理
前言 自然语言处理(Natural Language Processing)是计算科学领域与人工智能领域中的一个重要方向.它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法.自然语言处理 ...
- General mistakes in parallel computing
这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=97 March 11, 2013 General mistakes in ...
- Win10 系统安装Sql Server2008 R2 数据库遇到的问题及解决办法总结!
1.开始安装时,提示要先安装 “.NET Framework 3.5(包括.NET 2.0和3.0)”,之前已经下载好.NET Framework 3.5 sp1,安装时还是提示要先安装 “.NET ...
- atoi (String to Integer) leetcode
将字符串转化为数字,其注意事项有: Requirements for atoi: The function first discards as many whitespace characters a ...
- C++内联函数的使用
1.为什么要用内联函数? 在C++中我们通常定义以下函数来求两个整数的最大值: int max(int a, int b) { return a > b ? a : b; } 为这么一个小的操作 ...
- JSON parse error: Can not construct instance of model.Class: no suitable constructor found
reference:http://blog.csdn.net/qq_33642117/article/details/51909346 当类中没有定义构造函数时,系统会指定给该类加上一个空参数的构造函 ...
- windows定时执行python脚本
from:http://blog.csdn.net/Gpwner/article/details/77882131
- hdu 6441 Find Integer(费马大定理+勾股数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6441(本题来源于2018年中国大学生程序设计竞赛网络选拔赛) 题意:输入n和a,求满足等式a^n+b^ ...
- Fortran学习记录1(Fortran数据类型)
Fortran中的字符 Fortran中的常量 Fortran中的变量 Fortran的I-N规则 Fortran中的有效位数 Fortran中的申明 Fortran中的表达式 Fortran中的语句 ...
- [LOJ] 分块九题 3
https://loj.ac/problem/6279 区间修改,区间查询前驱. TLE无数,我觉得这代码最精髓的就是block=1000. 谜一样的1000. 两个启示: 块内可以维护数据结构,比如 ...