博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[洛谷P1368]工艺
阅读量:5032 次
发布时间:2019-06-12

本文共 1610 字,大约阅读时间需要 5 分钟。

题意

给定一个环,从任意一个点出发形成一个串,求这个串的最小字典序

思路

O(n)做法最小表示法不会,再见

按照处理环的套路,先倍长了再说


后缀数组SA

显然就是求最小的后缀,但是要注意这个后缀长度必须不小于n,后缀排序裸题(因为数据过水所以不需要离散化)


后缀自动机SAM

据说这道题被卡了但还是提一下

对倍长后的串建SAM之后,从root向下走最小的边走n次即可

Code;

#include
#define N 600005using namespace std;int n,m,len,a[N],sa[N],rk[N],tp[N],h[N],cnt[N];template
void read(T &x){ char c;int sign=1; while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48; while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;}void radix_sort(){ for(int i=0;i<=m;++i) cnt[i]=0; for(int i=1;i<=len;++i) cnt[rk[i]]++; for(int i=1;i<=m;++i) cnt[i]+=cnt[i-1]; for(int i=len;i>=1;--i) sa[cnt[rk[tp[i]]]--]=tp[i];}void get_sa(){ m=200; for(int i=1;i<=len;++i) rk[i]=a[i],tp[i]=i; radix_sort(); for(int t=1;t
<<=1) { int p=0; for(int i=1;i<=t;++i) tp[++p]=len-t+i; for(int i=1;i<=len;++i) if(sa[i]>t) tp[++p]=sa[i]-t; radix_sort(); swap(rk,tp); rk[sa[1]]=p=1; for(int i=2;i<=len;++i) rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+t]==tp[sa[i-1]+t]) ? p : ++p; if(p==len) break; m=p; }}void get_h()//可以不要qwq{ int ht=0; for(int i=1;i<=len;++i) rk[sa[i]]=i; for(int i=1;i<=len;++i) { int p=sa[rk[i]-1]; while(a[i+ht]==a[p+ht]) ++ht; h[rk[i]]=ht; ht=max(0,ht-1); }}int main(){ read(n);len=n*2; for(int i=1;i<=n;++i) read(a[i]),a[i+n]=a[i]; get_sa(); get_h(); int con=0,ans=len+1; for(int i=1;i<=len;++i) { if(con&&h[i]

转载于:https://www.cnblogs.com/Chtholly/p/11326080.html

你可能感兴趣的文章
oracle入门(4)——少而常用的命令
查看>>
打印机设置(PrintDialog)、页面设置(PageSetupDialog) 及 RDLC报表如何选择指定打印机...
查看>>
Java 虚拟机部分面试题
查看>>
JS中 String/JSON 方法总结
查看>>
二叉树的遍历问题总结
查看>>
3.14-3.20周总结
查看>>
Spring之面向切面编程AOP
查看>>
MATLAB GUI程序设计中使文本框接收多行输入的方法
查看>>
全文检索-Elasticsearch (四) elasticsearch.net 客户端
查看>>
Oracle DBMS_SESSION
查看>>
sublime复制当前行到下一行
查看>>
WPF 3D变换应用
查看>>
luogu4012 深海机器人问题 网络流
查看>>
android 拍照上传照片
查看>>
ArchLinux安装开源VMware Tools
查看>>
系统用户分析模型
查看>>
DB2 锁升级示例1
查看>>
16.RDD实战
查看>>
MainFrame知识小结(20120210)—dfsort/syncsort中的数据类型
查看>>
jsp题库 (一)小测(25/21)
查看>>