【Luogu5108】仰望半月的夜空(后缀数组)

题面

洛谷

题解

实名举报这题在比赛之前还不是这个样子的,还被我用SAM给水过去了

很明显求出\(SA\)之后就是按照\(SA\)的顺序从前往后考虑每一个长度,这样可以知道串是什么。

不过如果串相同要左端点最靠左,所以二分包含这个串的区间,用\(RMQ\)求出区间最小值即可。

(其实就是拿来复习SA板子的)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 400200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,sig;
char ch[MAX];
int S[MAX],tot,a[MAX],lg[MAX];
int t[MAX],x[MAX],y[MAX],rk[MAX],SA[MAX],hg[20][MAX],mn[20][MAX];
bool cmp(int i,int j,int k){return y[i]==y[j]&&y[i+k]==y[j+k];}
void GetSA()
{
int m=tot;
for(int i=1;i<=n;++i)t[x[i]=a[i]]++;
for(int i=1;i<=m;++i)t[i]+=t[i-1];
for(int i=n;i>=1;--i)SA[t[x[i]]--]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=n-k+1;i<=n;++i)y[++p]=i;
for(int i=1;i<=n;++i)if(SA[i]>k)y[++p]=SA[i]-k;
for(int i=1;i<=m;++i)t[i]=0;
for(int i=1;i<=n;++i)t[x[y[i]]]++;
for(int i=1;i<=m;++i)t[i]+=t[i-1];
for(int i=n;i>=1;--i)SA[t[x[y[i]]]--]=y[i];
swap(x,y);x[SA[1]]=p=1;
for(int i=2;i<=n;++i)x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
if(p>=n)break;m=p;
}
for(int i=1;i<=n;++i)rk[SA[i]]=i;
for(int i=2;i<=n;++i)lg[i]=lg[i>>1]+1;
for(int i=1,j=0;i<=n;++i)
{
if(j)--j;
while(a[i+j]==a[SA[rk[i]-1]+j])++j;
hg[0][rk[i]]=j;
}
for(int j=1;j<=lg[n];++j)
for(int i=1;i+(1<<j)-1<=n;++i)
hg[j][i]=min(hg[j-1][i],hg[j-1][i+(1<<(j-1))]);
for(int i=1;i<=n;++i)mn[0][i]=SA[i];
for(int j=1;j<=lg[n];++j)
for(int i=1;i+(1<<j)-1<=n;++i)
mn[j][i]=min(mn[j-1][i],mn[j-1][i+(1<<(j-1))]);
}
int lcp(int i,int j)
{
if(i==j)return 1e9;i=rk[i];j=rk[j];
if(i>j)swap(i,j);i+=1;int k=lg[j-i+1];
return min(hg[k][i],hg[k][j-(1<<k)+1]);
}
int RMQ(int i,int j)
{
if(i>j)swap(i,j);int k=lg[j-i+1];
return min(mn[k][i],mn[k][j-(1<<k)+1]);
}
int main()
{
sig=read();n=read();
if(sig==26)
{
scanf("%s",ch+1);n=strlen(ch+1);
for(int i=1;i<=n;++i)a[i]=ch[i]-96;
}
else for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=n;++i)S[++tot]=a[i];
sort(&S[1],&S[n+1]);tot=unique(&S[1],&S[n+1])-S-1;
for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[tot+1],a[i])-S;
GetSA();
for(int i=1,p=1;i<=n;++i)
{
while(n-SA[p]+1<i)++p;
int l=p+1,r=n,ret=p;
while(l<=r)
{
int mid=(l+r)>>1;
if(lcp(SA[p],SA[mid])>=i)l=mid+1,ret=mid;
else r=mid-1;
}
printf("%d ",RMQ(p,ret));
}
puts("");return 0;
}

【Luogu5108】仰望半月的夜空(后缀数组)的更多相关文章

  1. 洛谷P5108 仰望半月的夜空(后缀数组)

    题意 题目链接 Sol warning:下面这个做法只有95分,本地拍了1w+组都没找到错误我表示十分无能为力 我们考虑每个串的排名去更新答案,显然排名为\(1\)的后缀的前缀一定是当前长度的字典序最 ...

  2. luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分

    仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...

  3. 洛谷 P5108 仰望半月的夜空 解题报告

    P5108 仰望半月的夜空 题目描述 半月的夜空中,寄托了多少人与人之间的思念啊 曦月知道,这些思念会汇集成一个字符串\(S(n = |S|)\) 由于思念汇集的过于复杂,因此曦月希望提炼出所有的思念 ...

  4. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  5. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  6. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  7. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  8. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  9. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

随机推荐

  1. Nagios数据存储插件NDOUtils部署和测试

    1. 概述 NDOUTILS,Nagios Data Output Utils,Nagios数据输出工具,允许用户从Nagios导出状态和事件信息到数据库中,便于以后的检索和加工 它包括几个部分: N ...

  2. Linux下部署Samba服务环境的操作记录

    关于Linux和Windows系统之间的文件传输,很多人选择使用FTP,相对较安全,但是有时还是会出现一些问题,比如上传文件时,文件名莫名出现乱码,文件大小改变等问题.相比较来说,使用Samba作为文 ...

  3. linux下监控某个目录是否被更改

    需求:对一个目录(比如/data/test)进行监控,当这个目录下文件或子目录出现变动(如修改.创建.删除.更名等操作)时,就发送邮件!针对上面的需求,编写shell脚本如下: [root@cento ...

  4. Centos 6.9下部署Oracle 11G数据库环境的操作记录

    操作系统:Centos6.9(64Bit)Oracle:11g .11.2.0.4.0版本Ip地址:172.16.220.139 废话不多说了,下面记录安装过程:1)安装桌面环境 [root@vm01 ...

  5. nginx下目录浏览及其验证功能、版本隐藏等配置记录

    工作中常常有写不能有网页下载东西的需求,在Apache下搭建完成后直接导入文件即可达到下载/显示文件的效果;而Nginx的目录列表功能默认是关闭的,如果需要打开Nginx的目录列表功能,需要手动配置, ...

  6. 代码规范(RL-TOC)用更合理的方式写 JavaScript

    代码可以改变世界 不规范代码可以毁掉世界 只有先学会写规范的代码,才可以走的更远 编程语言之间有很多编程规范都是通用: 命名 不要用语言不明的缩写,不用担心名字过长,名字一定要让别人知道确切的意思; ...

  7. 2-Twenty First Scrum Meeting-20151221

    任务安排 成员 今日完成 明日任务 闫昊 请假(数据库)   唐彬 请假(数据库)   史烨轩  尝试使用downloadmanager对notification进行更新  尝试使用downloadm ...

  8. answer my questions from the book<构建之法>.

    1)何为文档:文档时在一个项目进行的一生中所有记忆的集合.有需求分析.功能设计.在实现功能过程中也可以有一系列文档记录.测试文档等等. 2)结对工作等找队友会花费大量时间致耽误项目否:正如老师所讲,从 ...

  9. iOS开发CAAnimation详解

    Core Animation,即为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍.也就是说,使用少量的代码就可以实现非常强大的功能.Core Anima ...

  10. Using Android Phone to recover SD card formatted with DD command under linux

    Using Android Phone to recover SD card formatted with DD command under linux 1. Formatted a sd card ...