P3809 【模板】后缀排序

题目链接:https://www.luogu.org/problemnew/show/P3809

题目背景

这是一道模板题。

题目描述

读入一个长度为 nn 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置。位置编号为 11 到 nn。

输入输出格式

输入格式:

一行一个长度为 nn 的仅包含大小写英文字母或数字的字符串。

输出格式:

一行,共n个整数,表示答案。

输入输出样例

输入样例#1:

ababa
输出样例#1:

5 3 1 4 2

题解:

后缀数组模板题= =哇,后缀数组代码看了我好久,最终还是似懂非懂的,管他的,先用着/滑稽

其实我感觉后缀数组的思想还是比较好理解的,就是这个代码,基数排序那里有点迷,代码中有很多巧妙的细节吧,比如求前缀和后面倒着来求sa数组,我感觉这是最巧妙的地方了。

还有就是对第一、二关键字整体排序那里,倒序就保证了第一关键字从大到小,并且第二关键字也是从大到小...

废话不多说了,直接看代码吧...注释里面写了一些。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+;
int n;
char s[N];
int x[N],y[N],sa[N],c[N];
void Get_sa(int m){
n=strlen(s);
for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[i]=s[i]]++;//基数排序基本思想,c数组相当于一个桶
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;i>=;i--) sa[--c[x[i]]]=i;//求出sa数组,这里--c[x[i]]]是用来求出sa数组的下标的,注意弄懂sa数组的含义!!
for(int k=;k<=n;k++){
int 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;//第二关键字,y[i]表示与第i小的第二关键字配对的第一关键字位置
for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[i]]++;
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;i>=;i--) sa[--c[x[y[i]]]]=y[i];//倒序很巧妙,第二关键字最大的同时,第一关键字也是尽可能大的,sa数组的求法可参见上面
swap(x,y);
p=;x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=y[sa[i-]]==y[sa[i]]&&y[sa[i-]+k]==y[sa[i]+k]?p-:p++;//分别比较第一关键字和第二关键字
//这里x[i]表示的是后缀i的大小为多少,这里相当于将第一、第二关键字合并为第一关键字
if(p>=n) break ;
m=p;
}
}
int main(){
scanf("%s",s);
Get_sa();
int n=strlen(s);
for(int i=;i<n;i++) cout<<sa[i]+<<" ";
return ;
}

最新文章

  1. cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element &#39;mvc:annotation-driven&#39;.
  2. eclipse下的emacs风格快捷键
  3. C# .NET 隐藏窗体
  4. 101 个 MySQL 的调节和优化的提示(根据实际情况调整,有些已经不适用)
  5. 高德地图 JavaScript API 开发系列教程(二)
  6. 按照行拆分textarea
  7. Activity Threa创建Window和View分析
  8. DWZ在APS.NET WebForm中的使用(二)
  9. 一个关于native sql的程序
  10. Go实现短url项目
  11. Elastic Stack-Elasticsearch使用介绍(二)
  12. 优化算法:AdaGrad | RMSProp | AdaDelta | Adam
  13. patch 28729262
  14. CSS文字的跑马灯特效
  15. pwnable.tw unexploitable 分析
  16. 洛谷 P1163&quot;银行贷款&quot;(二分)
  17. Oracle12c从入门到精通(第二版) PDF 下载
  18. 使用impala操作kudu之创建kudu表(内部表和外部表)
  19. Terminating app due to uncaught exception &#39;NSInvalidArgumentException&#39;, reason: &#39;*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]&#39;
  20. 关于ES6的一些新特性的学习

热门文章

  1. [CF294B]Shaass and Bookshelf
  2. leetcode-最大子序和(动态规划讲解)
  3. Vuejs 基础与语法
  4. java并发总览
  5. 统计单词数:string函数使用
  6. Thunder团队第二周 - Scrum会议5
  7. return语句的用法
  8. 《剑指offer》---跳台阶问题
  9. Js键盘事件全面控制,回车按键事件,键盘对应按键码,按键事件兼容各个浏览器。
  10. C#控件DropDownList下拉列表默认打开