luogu P3809 【模板】后缀排序
嘟嘟嘟
今天学了一个后缀数组,还是挺好理解的。
因为我不会基数排序,所以只会\(O(n \log ^ 2 n)\)的sort版。
首先,后缀数组就是把该字符串的所有后缀按字典序排序得到的一个数组。注意这个排序只有字典序一个关键字,跟长度无关。
比如ababa的后缀数组就是:5 3 1 4 2,对应的后缀为a, aba, ababa, ba, baba。
怎么求呢?
特别好理解。
就像st表一样倍增的求。
令\(s[i][k]\)表示以\(i\)为起点,长度为\(2 ^ k\)的子串(如果\(i + 2 ^ k > n\),则表示从\(i\)开始的后缀)。\(rank_k[i]\)表示他是第几小的。
那么如果要比较\(s[i][k + 1]\)和\(s[j][k + 1]\),只需比较\(s[i][k], s[i + 2 ^ k][k]\)和\(s[j][k], s[j + 2 ^ k][k]\)的排名。换句话说,这一次的排序。就是以\(rank[s[i][k]]\)为第一关键字,\(rank[s[i + 2 ^ k][k]]\)为第二关键字进行排序。
排完序后,再\(O(n)\)扫一遍更新\(rank\)数组。
分治每一层为\(O(n \log n)\),一共\(\log n\)层,所以总复杂度为\(O(n \log ^ 2 n)\)。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e6 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, k;
char s[maxn];
int sa[maxn], rnk[maxn], tp[maxn];
In bool cmp(int i, int j)
{
if(rnk[i] != rnk[j]) return rnk[i] < rnk[j];
int x = i + k <= n ? rnk[i + k] : -1;
int y = j + k <= n ? rnk[j + k] : -1;
return x < y;
}
int main()
{
scanf("%s", s + 1);
n = strlen(s + 1);
for(int i = 1; i <= n; ++i) sa[i] = i, rnk[i] = s[i];
//刚开始的rank可以直接用ASCII码
for(k = 1; k <= n; k <<= 1)
{
sort(sa + 1, sa + n + 1, cmp);
for(int i = 1; i <= n; ++i)
tp[sa[i]] = tp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) ? 1 : 0);
for(int i = 1; i <= n; ++i) rnk[i] = tp[i];
}
for(int i = 1; i <= n; ++i) write(sa[i]), space; enter;
return 0;
}
luogu P3809 【模板】后缀排序的更多相关文章
- 洛谷.3809.[模板]后缀排序(后缀数组 倍增) & 学习笔记
题目链接 //输出ht见UOJ.35 #include<cstdio> #include<cstring> #include<algorithm> const in ...
- UOJ.35.[模板]后缀排序(后缀数组 倍增)
题目链接 论找到一个好的教程的正确性.. 后缀数组 下标从1编号: //299ms 2560kb #include <cstdio> #include <cstring> #i ...
- 洛谷:P3809 【模板】后缀排序(后缀数组模板)
P3809 [模板]后缀排序 题目链接:https://www.luogu.org/problemnew/show/P3809 题目背景 这是一道模板题. 题目描述 读入一个长度为 nn 的由大小写英 ...
- P3809 【模板】后缀排序
P3809 [模板]后缀排序 从这学的 后缀数组sa[i]就表示排名为i的后缀的起始位置 x[i]是第i个元素的第一关键字 y[i]表示第二关键字排名为i的数,在第一关键字中的位置 #include& ...
- [洛谷P3809]【模板】后缀排序
[洛谷P3809][模板]后缀排序 题目大意: 对于给定的长度为\(n(n\le10^6)\)的字符串求后缀数组\(sa[i]\). 思路: 倍增+快排构造后缀数组.代码参考<挑战程序设计竞赛& ...
- 【模板】后缀排序(SA数组)
[模板]后缀排序 题目背景 这是一道模板题. 题目描述 读入一个长度为 \(n\) 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字 ...
- LG3809 【模板】后缀排序
题意 题目背景 这是一道模板题. 题目描述 读入一个长度为 $ n $ 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的 ...
- codevs1500 后缀排序
题目描述 Description 天凯是MIT的新生.Prof. HandsomeG给了他一个长度为n的由小写字母构成的字符串,要求他把该字符串的n个后缀(suffix)从小到大排序. 何谓后缀?假设 ...
- UOJ#35 后缀排序
这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编号为 1 到 n. 除此之外为 ...
- 2018.11.24 loj#111. 后缀排序(后缀数组)
传送门 后缀排序模板题. 终于会后缀数组了(然而只会倍增并不会DC3DC3DC3). 在这里列举几个数组的意思: sai:sa_i:sai:当前排名第iii的后缀的起始下标. rkirk_irki ...
随机推荐
- Python 判断文件/目录是否存在
使用 os 模块 判断文件是否存在 os.path.isfile(path) 判断目录是否存在 os.path.isdir(path) 判断路径是否存在 # 使用 path 模块 os.path.ex ...
- [HEOI2016] 字符串
Description 给定长度为n的字符串,m次询问,每次询问s[a...b]的所有子串与s[c...d]的LCP的最大值.n,m<=10^5. Solution 感觉这种n,m<=10 ...
- Java 使用 happen-before 规则实现共享变量的同步操作
前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen-before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结 ...
- Eclipse SVN 冲突的 介绍 及 四种解决方式
https://blog.csdn.net/diyu122222/article/details/79879376
- ip2Long 代码
def ip2Long(ip: String): Long = { val fragments = ip.split("[.]") var ipNum = 0L for (i &l ...
- 百度网盘满速下载器:pandownload
http://pandownload.com/index.html 作者提示:1.软件使用 C++ 编写2.大文件需要等待一段时间才会有下载速度3.文件名含有特殊字符可能会下载出错,请重命名再下载4. ...
- 【代码笔记】Web-HTML-段落
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- 搜狐eHR团队-曾经一起奋斗过的~
昨天所有搜狐eHR团队同事再相聚(在职+离职),大家聊的都很开心,共同回顾了eHR项目从无到有的过程. 非常感谢在搜狐的工作经历,自己成长很多,目前大家分布在各个公司为eHR做着贡献,大家都注意身体~ ...
- LyX快捷键管理
快捷键修改:Tools->Preference->Editing->Shortcuts:修改后要Tools->Reconfig生效 快捷键默认保存文件:%appdata%\Ly ...
- JavaScript变量提升的理解
变量提升 先说三句总结性的话: let 的「创建」过程被提升了,但是初始化没有提升. var 的「创建」和「初始化」都被提升了. function 的「创建」「初始化」和「赋值」都被提升了. 所以,我 ...