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 ;
}

洛谷:P3809 【模板】后缀排序(后缀数组模板)的更多相关文章

  1. [洛谷P3809]【模板】后缀排序

    [洛谷P3809][模板]后缀排序 题目大意: 对于给定的长度为\(n(n\le10^6)\)的字符串求后缀数组\(sa[i]\). 思路: 倍增+快排构造后缀数组.代码参考<挑战程序设计竞赛& ...

  2. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  3. 洛谷P3809 后缀数组模板

    题目:https://www.luogu.org/problemnew/show/P3809 刚学了后缀数组,看人家手写演示了半天,大概明白了过程,但完全写不出来代码: 于是借鉴了许多,不过都差不多, ...

  4. 洛谷P3763 [Tjoi2017]DNA 【后缀数组】

    题目链接 洛谷P3763 题解 后缀数组裸题 在BZOJ被卡常到哭QAQ #include<algorithm> #include<iostream> #include< ...

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

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

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

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

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

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

  8. 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器

    刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...

  9. [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)

    洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...

  10. 洛谷1726 上白泽慧音 tarjan模板

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

随机推荐

  1. 用 splice 函数分别实现 push、pop、shift、unshift 的方法

    主要需要注意的是不同方法他们本身返回的值应该是什么,是数组当前的长度,还是取出的元素的值,再在splice函数里面进行相应的return就可以了.具体如下: 用 splice函数实现 push方法 f ...

  2. lock+Condition

    关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象.Condition ...

  3. Python3中@的作用

    可能是自己理解能力差,网上看了一大堆教程,完全没搞懂. 自己敲几行代码,终于理解是怎么回事了. #python 3.6 #!/usr/bin/env python # -*- coding:utf-8 ...

  4. Java学习笔记-13.创建窗口和程序片

    1.init()方法:程序片第一次被创建,初次运行初始化程序片时调用. start()方法:每当程序片进入web浏览器中,并且允许程序片启动他的常规操作时调用(特殊的程序片被stop()关闭):同样在 ...

  5. 洛谷 P1781 宇宙总统:sort(string)

    题目描述 地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有n个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统. 输入输出格式 输入格式: 第一行为一个整数n,代表竞选 ...

  6. Ext JS 6学习文档–第2章–核心概念

    核心概念 在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目.这一章我们将学习以下知识点: 类系统,创建和扩展类 事件 Ext JS ...

  7. 一道java笔试题

    输入一串用空格隔开的数字串,对于数字串的奇数位按升序排序,偶数位按降序排序. 示例输入: 4 6 2 3 6 7 8 1 处理过程: 奇数位:4 2 6 8 升序排序结果: 2 4 6 8 偶数位:6 ...

  8. 20145214实验二 Java面向对象程序设计

    20145214实验二 Java面向对象程序设计 初步掌握单元测试和TDD 三种代码 伪代码 `百分制转五分制:` `如果成绩小于60,转成"不及格"` `如果成绩在60与70之间 ...

  9. 重构 之 总结代码的坏味道 Bad Smell (一) 重复代码 过长函数 过大的类 过长参数列 发散式变化 霰弹式修改

    膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...

  10. Internet History

    Alan Turing and Bletchley Park Top secret breaking effort(二战破译希特勒密码) 10,000 people at the peak(team ...