UOJ #35. 后缀排序 后缀数组 模板
http://uoj.ac/problem/35
模板题,重新理了一遍关系。看注释吧。充分理解了倍增的意义,翻倍之后对上一次排序的利用是通过一种类似于队列的方式完成的。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int maxn=200010; 8 const int pl=50; 9 int sa[maxn+pl]={};//排名第i的是从sa[i]开始的数组 10 int rk[maxn+pl]={};//i的排名 11 int height[maxn+pl]={};//排名第i的与排名第i-1的最长相同前缀长度 12 int temp[maxn+pl]={};//暂时的排名 13 int cnt[maxn+pl]={};//第i种(字典序)前缀的有多少个(的前缀和) 14 int p[maxn+pl]={};//此次需要排列的sa的储存,处理了后缀长度不同的情况。 15 char ch[maxn+pl]={}; 16 int siz; 17 bool equ(int x,int y,int l){ return rk[x]==rk[y]&&rk[x+l]==rk[y+l]; } 18 void SA(){ 19 for(int i=1;i<=siz;i++){rk[i]=ch[i];sa[i]=i;} 20 for(int i,sig=255,l=0,pos=0;pos<siz;sig=pos){ 21 pos=0; 22 for(i=siz-l+1;i<=siz;i++)p[++pos]=i;//根据上一次的sa决定p的储存顺序,没有排序则排在最前。 23 for(i=1;i<=siz;i++) if(sa[i]>l) p[++pos]=sa[i]-l;//sa的计算是向字符串前端(左侧)拓展的 24 for(i=1;i<=sig;i++) cnt[i]=0; 25 for(i=1;i<=siz;i++) cnt[rk[p[i]]]++; 26 for(i=1;i<=sig;i++) cnt[i]+=cnt[i-1]; 27 for(i=siz;i>0;i--) sa[cnt[rk[p[i]]]--]=p[i];//方便记忆板子的提示,只有这里是倒着扫的。 28 pos=0; 29 for(i=1;i<=siz;i++){ 30 if(equ(sa[i],sa[i-1],l))temp[sa[i]]=pos; 31 else temp[sa[i]]=++pos; 32 } 33 for(int i=1;i<=siz;i++)rk[i]=temp[i]; 34 if(!l)l=1; 35 else l<<=1; 36 }int j=0; 37 for(int i=1;i<=siz;i++){ 38 if(rk[i]==1){j=0;continue;} 39 if(j)j--; 40 while(ch[i+j]==ch[sa[rk[i]-1]+j]){ 41 j++; 42 }height[rk[i]]=j; 43 } 44 } 45 int main(){ 46 //freopen("a.in","r",stdin); 47 scanf("%s",ch+1);siz=strlen(ch+1); 48 SA(); 49 for(int i=1;i<=siz;i++)printf("%d ",sa[i]); 50 cout<<endl; 51 for(int i=2;i<=siz;i++)printf("%d ",height[i]); 52 return 0; 53 }
View Code
转载于:https://www.cnblogs.com/137shoebills/p/8511439.html
UOJ #35. 后缀排序 后缀数组 模板相关推荐
- UOJ.35.[模板]后缀排序(后缀数组 倍增)
题目链接 论找到一个好的教程的正确性.. 后缀数组 下标从1编号: //299ms 2560kb #include <cstdio> #include <cstring> #i ...
- 后缀数组 java实现_后缀数组模板 - java开发指南博客 【转载】 - ITeye博客
//后缀数组模板 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];//这些都是需要用到的中间变量 int cmp(int *r,int a,int b,int l) { ...
- c++ 字符串数组长度排序_数组 | 后缀数组的求法及应用
作者:Andy__lee 链接:https://blog.nowcoder.net/n/6b4a93e186ed4a358321de6a7c3b4f19 来源:牛客网 定义 维基百科 - 后缀数组 让 ...
- 【BZOJ 1031】[JSOI2007]字符加密Cipher(后缀数组模板)
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1031 [题意] [题解] 后缀数组模板题; 把整个字符串扩大一倍. 即长度乘2 然后搞 ...
- 后缀数组模板 hdu1403
题意:就是让你求两个字符串的最大子串 #include <bits/stdc++.h> const int maxn=200005; using namespace std; int s[ ...
- 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)
常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...
- 数组的选择--固定大小数组模板array存在的意义!
主要就是为了使用的方便,更加容易和algorithm的算法结合的更好! #include <iostream> #include <ctime> #include <ar ...
- python【力扣LeetCode算法题库】面试题 10.01-合并排序的数组
面试题 10.01. 合并排序的数组 给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B. 编写一个方法,将 B 合并入 A 并排序. 初始化 A 和 B 的元素数量分别为 m ...
- HDU1166 敌兵布阵(树状数组模板题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
最新文章
- opencv 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突
- (Incomplete) UVa 719 Glass Beads
- 机器学习算法加强——决策树和随机森林实践
- boost::hana::sizeof_用法的测试程序
- 【maven插件】asciidoctor-maven-plugin:编译Asciidoc
- 03 php,PHP 03 选择结构
- STL 中的链表排序
- 面向IT专业人员的8个新兴AI工作
- (转)淘淘商城系列——实现添加商品功能
- php7 安装memcached、memcache
- oracle归档日志太多(ORA-00257: archiver error. Connect internal only, until freed)错误的处理方法
- 记录自己的第一次实习
- Python菜鸟入门:day17编程学习
- 判断单链表是否存在环及环的入口点
- python esp8266 ssd1306_micropython esp8266+ssd1306(OLED) 显示中文(示例)
- Wifi热点工具-青青草原WiFi
- 难倒高手了,c语言枚举end的作用是什么?
- Sparse Local Patch Transformer for Robust Face Alignment and Landmarks Inherent Relation Learning
- SAP中销售处理到期发票清单VF04功能的应用
- NodeJS 创建静态资源服务器
热门文章
- 大数据如何学习 cda认证_第十届CDA认证考试 LEVEL 1 优秀考生访问录:我是如何备考的?...
- 地址突然就不对了_【装维大课堂】光猫的无线WiFi功能突然无法使用
- js websocket同步等待_WebSocket硬核入门:200行代码,教你徒手撸一个WebSocket服务器...
- mysql报196271错误_超过mysql最大连接的异常
- python【力扣LeetCode算法题库】100-相同的树
- 二分查找对应的二叉树的成功和失败ASL
- 习题1.9 有序数组的插入 (20 分)
- python基础练习(七)
- redis value最大值_Redis 的 maxmemory 和 dbnum 默认值都是多少?对于最大值会有限制吗?...
- 上海网络推广为大家讲解细节标签能给网站带来的作用与效果!