题目链接

//输出ht见UOJ.35
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=1e6+5; int n,tm[N],t1[N],t2[N],SA[N],rk[N],ht[N];
//SA[i]=j:排名为i的后缀开头的下标为j
//rk[i]=j:以下标i开头的后缀排名为j
//ht[i]:排名为i的后缀与排名为i-1的后缀的LCP长度
char s[N]; void Get_SA()
{
int *x=t1,*y=t2,limit=80;//首先对单个字符进行排序,limit最初就为字符集大小(就是不同字符的个数)
for(int i=0;i<n;++i) ++tm[x[i]=s[i]-'0'];
for(int i=1;i<limit;++i) tm[i]+=tm[i-1];
for(int i=n-1;~i;--i) SA[--tm[x[i]]]=i;//基数排序
//x[]相当于是rank值
for(int p=0,k=1;k<n;k<<=1,limit=p,p=0)//每次更新limit为p
{//p实际就是新一轮基数排序后 不同后缀的个数
//首先对第二关键字进行排序,y保存的就是对第二关键字排序后的结果
//这一过程可以直接用上次得到的SA[]求出
for(int i=n-k;i<n;++i) y[p++]=i;//第二关键字长度不为k,故先排
for(int i=0;i<n;++i) if(SA[i]>=k) y[p++]=SA[i]-k;//剩下的有完整第二关键字的(SA[i]>=k)按顺序,即SA[i]排,第一关键字的位置自然就是SA[i]-k
//对第一关键字的排序同对单个字符排序
for(int i=0;i<limit;++i) tm[i]=0;
for(int i=0;i<n;++i) ++tm[x[i]];//++tm[x[y[i]]];
for(int i=1;i<limit;++i) tm[i]+=tm[i-1];
for(int i=n-1;~i;--i) SA[--tm[x[y[i]]]]=y[i];//这个双关键字基数排序我现在也还是感觉好迷好nb=-= 并不很懂
//交换两个指针,因为要用到上一轮的rk(x),而y是没有用了
std::swap(x,y), x[SA[0]]=0, p=1;
//得到新的rank
for(int i=1;i<n;++i)
// x[SA[i]]=(y[SA[i-1]]==y[SA[i]]&&y[SA[i-1]+k]==y[SA[i]+k])?p-1:p++;//对于连续字符的字符串会WA //但是字符串下标从1开始(s[i]-'a'+1)就没事了...但注意要清空
if(y[SA[i-1]]==y[SA[i]]&&((y[SA[i-1]+k]==y[SA[i]+k]&&SA[i-1]+k<n&&SA[i]+k<n)||(SA[i-1]+k>=n&&SA[i]+k>=n))) x[SA[i]]=p-1;
else x[SA[i]]=p++;
if(p>=n) break;//不同字符串数已有n个,再继续倍增不会变了,break
}
}
void Calc_Ht()
{
for(int i=0;i<n;++i) rk[SA[i]]=i;//rk[]与SA[]互为反函数
// 有一个性质是:ht[rk[i]]>=ht[rk[i-1]]-1
// 因为去掉开头字符 后缀一大部分是相等的。比较明显
for(int j,k=0,i=0;i<n;ht[rk[i++]]=k)
{
if(!rk[i])// continue;//排名为0的字符串ht为0
{ht[0]=0;continue;}
j=SA[rk[i]-1], k?--k:0;//从k-1开始匹配(与上一名次字符串)
while(s[i+k]==s[j+k]&&i+k<n&&j+k<n) ++k;
}
} int main()
{
// freopen("sais.in","r",stdin);
// freopen("sais.out","w",stdout); scanf("%s",s),n=strlen(s);
Get_SA();
Calc_Ht();
for(int i=0;i<n;++i) printf("%d ",SA[i]+1);
putchar('\n');
for(int i=1;i<n;++i) printf("%d ",ht[i]); return 0;
}

洛谷.3809.[模板]后缀排序(后缀数组 倍增) & 学习笔记的更多相关文章

  1. 洛谷4455 [CQOI2018]社交网络 (有向图矩阵树定理)(学习笔记)

    sro_ptx_orz qwq算是一个套路的记录 对于一个有向图来说 如果你要求一个外向生成树的话,那么如果存在一个\(u\rightarrow v\)的边 那么\(a[u][v]--,a[v][v] ...

  2. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

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

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

  4. 洛谷 3379 最近公共祖先(LCA 倍增)

    洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...

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

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

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

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

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

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

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

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

  9. 洛谷P3375 [模板]KMP字符串匹配

    To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...

随机推荐

  1. CSS在项目中常用的属性总结

    1.媒体查询 2.如何快速生成适配各种浏览器的属性. 3.全面进军移动app开发.

  2. HTTP协议中PUT和POST使用上的区别

    有的观点认为,应该用POST来创建一个资源,用PUT来更新一个资源:有的观点认为,应该用PUT来创建一个资源,用POST来更新一个资源:还有的观点认为可以用PUT和POST中任何一个来做创建或者更新一 ...

  3. MySQL— 基础

    目录 一.MySQL概述 二.下载安装 三.数据库操作 四.数据表操作 五.表内容操作 一.MySQL概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracl ...

  4. 使用 GDebi 默认代替 Ubuntu 软件中心

    GDebi,一个安装 Debian 可执行文件的专用程序.它极其轻量,且专注于安装 .deb 文件,可以自动解决依赖问题,比原生的好用.GDebi 最有用的功能是它也可以为你展示出将要安装的程序的依赖 ...

  5. Qt5.8 在windows下mingw静态编译

    官方对编译一些条件介绍:https://doc.qt.io/qt-5/windows-requirements.html 在默认情况下,用QtCreator编译程序时,使用的是动态编译.编译好的程序在 ...

  6. MyEclipse 2015反编译插件安装

    本文转自 MyEclipse 2015反编译插件安装 分享一下下载插件的地址,百度网盘:链接:http://pan.baidu.com/s/1nturiAH 密码:yk73 其次:我来说下具体操作步骤 ...

  7. hdu3486 ST表区间最值+二分

    还是挺简单的,但是区间处理的时候要注意一下 #include<iostream> #include<cstring> #include<cstdio> #inclu ...

  8. 《剑指offer》-判断对称二叉树

    题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 思路上还是广度优先搜索(BFS)来做的.BFS是依托于STL的queue作为容 ...

  9. 基于OSGI.NET的MVC插件式开发

    最近在研究OSGI.NET插件式开发框架.官方网站提供了一个基于OSGI.NET的插件仓库.下载官方的SDK包安装后VS项目模板会多出一组iOpenWorks项目模板.在学习过程中,发现通过iOpen ...

  10. Ubuntu14.04 安装MySQL 及Can‘t connect to local MYSQL server through socket ’/var/run/mysqld/mysqld.sock‘ (2)

    今天安装Mysql 按着这个①http://www.cnblogs.com/zhuyp1015/p/3561470.html来安装,却出现了这个问题 卸载又从安装还是有问题, 搜了好久在stackov ...