洛谷P3809 后缀数组模板
2024-08-31 03:06:31
题目:https://www.luogu.org/problemnew/show/P3809
刚学了后缀数组,看人家手写演示了半天,大概明白了过程,但完全写不出来代码;
于是借鉴了许多,不过都差不多,总算会写了;
如何把想法实现出来很重要啊...
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=1e6+;
int n,m,rk[maxn],tp[maxn],sa[maxn],a[maxn],num,tax[maxn];
char s[maxn];
void Rsort()
{
for(int i=;i<=m;i++)tax[i]=;
for(int i=;i<=n;i++)tax[rk[tp[i]]]++;
for(int i=;i<=m;i++)tax[i]+=tax[i-];
for(int i=n;i;i--)sa[tax[rk[tp[i]]]--]=tp[i];//tp是位置,rk是该位置第一关键字排名,tax存数量
//tp[i]是第二关键字从小到大进入,所以从大到小出来就可以使用前缀
}
void work()
{
for(int i=;i<=n;i++)rk[i]=a[i],tp[i]=i;
Rsort();
for(int k=;k<=n;k<<=)
{
num=;
for(int i=n-k+;i<=n;i++)tp[++num]=i;//n-k以后的i后缀第二关键字是0,字典序最小
for(int i=;i<=n;i++)//枚举排名(上一次的,也就是本次第一关键字)
if(sa[i]>k)tp[++num]=sa[i]-k;//排名从小到大,其所在位置如果大于k,则可以作为本次第二关键字
//sa[i]-k 是位置,若上一次的第i名作为本次第二关键字,则所得后缀的位置在sa[i]-k
Rsort();
swap(rk,tp);//tp存下上一次排名,也就是本次第一关键字的排名
rk[sa[]]=;
num=;
for(int i=;i<=n;i++)
rk[sa[i]]=(tp[sa[i]]==tp[sa[i-]]&&tp[sa[i]+k]==tp[sa[i-]+k])?num:++num;
//比较前后两半排名是否相同
if(num==n)break;
m=num;//m是种类
}
}
int main()
{
cin>>s;
n=strlen(s); m=;
for(int i=;i<=n;i++)a[i]=s[i-];
work();
for(int i=;i<=n;i++)printf("%d ",sa[i]);
return ;
}
最新文章
- ParamTest
- Bean的定义及作用域的注解实现
- hdu 4034 Graph (floyd的深入理解)
- cf754 B. Ilya and tic-tac-toe game
- .net MVC APi调用
- HIT 1867 经理的烦恼
- MySQL基金会-基本数据库操作
- 第一百二十八节,JavaScript,Ajax
- CCF-201412-1-门禁系统
- SpringBoot+mybatis使用@Transactional无效
- Linux笔记-ps -aux的结果解析
- LeetCode 第五题 最长的回文字符串 (JAVA)
- linux配置无秘钥登陆
- ios 获取视频截图
- 阿里NLP总监分享-NLP技术的应用与思考
- sqrtx-开平方
- Android实践项目汇报(总结)
- Speeding up Homestead on Windows Using NFS
- tkinter的GUI设计:界面与逻辑分离(一)-- 初次见面
- git源代码管理工具
热门文章
- 用最简单的脚本完成supertab的基本功能并实现一个更加合理的功能
- THREE.js代码备份——canvas - geometry - earth(球体贴纹理)
- Cesium学习笔记(四)Camera ----http://blog.csdn.net/hobhunter/article/details/74909641
- img、a标签的使用
- openstack——cinder服务篇
- [如何在Mac下使用gulp] 1.创建项目及安装gulp
- Java 初学者
- django访问静态变量的设置
- 《零压力学Python》 之 第二章知识点归纳
- hadoop-hdp-ambari离线安装记录