【后缀数组】后缀排序
来源:互联网 发布:淘宝哪家鞋子质量好 编辑:程序博客网 时间:2024/05/17 03:48
最近几天有很多题目没有写,尽量补上吧。hz2016评测《《点击访问caioj《《点击访问后缀数组》后缀自动机树状数组》线段树其实两种都是用一个特殊的简单结构,维护一部分高级算法的查询结构。后缀自动机顾名思义,就是处理后缀的啦,这道题是模板题,把数组的所有后缀按照大到小排序。具体还是看代码注释吧,结合代码会比较好理解。#include<map>#include<queue>#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define Maxchar 1524288 //1000000 +2^19#define Maxs 30#define mes(x,y) memset(x,y,sizeof(x));#define mpy(x,y) memcpy(x,y,sizeof(x))#define INF 2147483647using namespace std;int a[Maxchar+1],tt[Maxchar+1];char s[Maxchar+1];int Rank[Maxchar+1],sa1[Maxchar+1],Rank2[Maxchar+1],sa2[Maxchar+1],Rsort[Maxchar+1];//Rank名次数组: 你排第几?sa后缀数组:排第几的是谁?(记录是的起始位置) 后面的数字表示第几关键字void get_sa(int n,int m){ memcpy(Rank,a,sizeof(Rank)); //预处理第一关键字的排名:对长度为1的字符串进行基数排序,求出sa memset(Rsort,0,sizeof(Rsort)); for(int i=1;i<=n;i++)Rsort[Rank[i]]++; for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1]; for(int i=n;i>=1;i--)sa1[Rsort[Rank[i]]--]=i; int ln=1,p=0;//ln为当前处理好的子串的长度,p表示有多少不相同的子串 while(p<n){//现在处理的是长度为ln*2的子串,开始将两个关键字合并排序 //为啥不写ln<=n?因为有可能不需要排到ln=n就排完了,而当p==n就说明全部字符串不同,后面再也不会改变 int k=0;//处理第二关键字的排名: for(int i=n-ln+1;i<=n;i++)sa2[++k]=i;//先把要补0的后缀处理好,他们肯定在前面 for(int i=1;i<=n;i++)if(sa1[i]-ln>0)sa2[++k]=sa1[i]-ln;//sa1[i]是sa1[i]-ln的第二关键字,因为我们枚举的是第二关键字的排名 //sa2记录sa1[i]-ln的第二关键字的排名,指向sa1[i]-ln memset(Rsort,0,sizeof(Rsort)); for(int i=1;i<=n;i++)Rsort[Rank[i]]++; for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1]; for(int i=n;i>=1;i--)sa1[Rsort[Rank[sa2[i]]]--]=sa2[i]; for(int i=1;i<=n;i++)tt[i]=Rank[i];//由于Rank会改变,判断不了一、二关键字是否相等 //用sa得到新的Rank数组,为什么预处理的时候不能求出Rank?因为原来的Rank没有两个关键字 p=1;Rank[sa1[1]]=1; for(int i=2;i<=n;i++){ if(tt[sa1[i]]!=tt[sa1[i-1]]||tt[sa1[i]+ln]!=tt[sa1[i-1]+ln] )p++; //一二关键字其中一个不同,前后的字符串不同 Rank[sa1[i]]=p; } m=p;ln*=2; }} int main(){ scanf("%s",s+1); int len=strlen(s+1); for(int i=1;i<=len;i++)a[i]=s[i]-'a'+1; get_sa(len,Maxs+1); for(int i=1;i<len;i++)printf("%d ",sa1[i]);printf("%d\n",sa1[len]); return 0;}具体就是这样啦,大家赶快做题吧。
查看原文:http://hz2016.tk/blog/?p=28
阅读全文
0 0
- 【后缀数组】后缀排序
- UOJ35 后缀排序 后缀数组
- uoj#35. 后缀排序 后缀数组
- Codevs_P1500 后缀排序(后缀数组+基数排序)
- 【UOJ 35】 后缀排序|后缀数组
- 【UOJ 35】 后缀排序|后缀数组 *2
- 【UOJ 35】 后缀排序|后缀数组 *3
- UOJ #35 后缀排序(后缀数组)
- Codevs 1500 后缀排序(后缀数组)
- Uoj #35. 后缀排序(后缀数组)
- 后缀子串排序(后缀数组)
- 后缀树/后缀数组
- 后缀树 后缀数组
- 后缀数组入门题——2323后缀排序
- [省选前题目整理][UOJ 35]后缀排序(后缀数组)
- UOJ #35. 后缀排序(后缀数组模板题)
- UOJ #35. 后缀排序 后缀数组模板题
- UOJ #35. BZOJ 1031 后缀排序 后缀数组模板
- ROS Service的使用_Python
- Innodb Cluster 入门(2) Mysql二进制日志
- SSL P2743 看电影
- 离散化-线段树-扫描线小结
- HDU 1258-Sum It Up(dfs)
- 【后缀数组】后缀排序
- android学习笔记(一)
- 《Linux程序设计》 -> 《Linux高级程序设计》 -> 《Unix环境高级编程》
- FM1702sl终于调通小结
- First Unique Number In Stream
- windows下nginx安装、配置与使用
- request对象的主要方法
- [Usaco2005 Oct]Allowance 津贴
- <Python和Pygame游戏开发指南>1