P5108 仰望半月的夜空
题目链接
题意分析
给你一个字符串 让你求\(1-n\)长度下的字符串的中字典序最小并且最靠左的字符串的开头位置
我们考虑先建出\(SA\)
然后考虑对于一个字符串后缀排序之后
baba
后缀排序之后 先不管位置 只关心字典序
数字代表当前更新长度
a 1
aba 2 3
ba
baba 4
我们可以发现 第二个后缀还可以更新长度为\(1\)的子串
所以我们考虑使用二分 求刚好可以满足的位置
然后我们再使用\(RMQ\)求这些位置中对应原串位置最靠左的位置
然后更新即可
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>
#define ll long long
#define inf 0x7fffffff
#define N 500008
#define IL inline
#define M 608611
#define D double
#define ull unsigned long long
#define R register
using namespace std;
template<typename T>IL void read(T &_)
{
T __=0,___=1;char ____=getchar();
while(!isdigit(____)) {if(____=='-') ___=0;____=getchar();}
while(isdigit(____)) {__=(__<<1)+(__<<3)+____-'0';____=getchar();}
_=___ ? __:-__;
}
/*-------------OI使我快乐-------------*/
char s[M];
int n,key,have;int num[M],res[M],ans[M];
int ST[M][20][2],lg[M];
int SA[M],rnk[M],cdy[M],wzy[M],vis[M],hei[M];
IL void Rsort()
{
for(R int i=0;i<=key;++i) vis[i]=0;
for(R int i=1;i<=n;++i) vis[cdy[i]]++;
for(R int i=1;i<=key;++i) vis[i]+=vis[i-1];
for(R int i=n;i;--i) SA[vis[cdy[wzy[i]]]--]=wzy[i];
}
IL void get_SA()
{
for(R int i=1;i<=n;++i) cdy[i]=num[i],wzy[i]=i;Rsort();
for(R int x=1;x<=n;x<<=1)
{
int cnt=0;
for(R int i=n-x+1;i<=n;++i) wzy[++cnt]=i;
for(R int i=1;i<=n;++i) if(SA[i]>x) wzy[++cnt]=SA[i]-x;
Rsort();swap(cdy,wzy);cdy[SA[cnt=1]]=1;
for(R int i=2;i<=n;++i)
cdy[SA[i]]=(wzy[SA[i]]==wzy[SA[i-1]]&&wzy[SA[i]+x]==wzy[SA[i-1]+x] ? cnt:++cnt);
if(cnt==n) break;
else key=cnt;
}
}
IL void get_hei()
{
for(R int i=1;i<=n;++i) rnk[SA[i]]=i;
int lat,k=0;
for(R int i=1;i<=n;++i)
{
if(k) --k;
lat=SA[rnk[i]-1];
while(num[lat+k]==num[i+k]) ++k;
hei[rnk[i]]=k;
}
}
IL void pre()
{
for(R int i=1;(1<<i)<=300000;++i) lg[1<<i]=i;
for(R int i=2;i<=300000;++i) if(!lg[i]) lg[i]=lg[i-1];
for(R int i=1;i<=n;++i) ST[i][0][0]=hei[i];
for(R int j=1;(1<<j)<=n;++j)
for(R int i=1;i<=n;++i)
ST[i][j][0]=min(ST[i][j-1][0],ST[i+(1<<(j-1))][j-1][0]);
for(R int i=1;i<=n;++i) ST[i][0][1]=SA[i];
for(R int j=1;(1<<j)<=n;++j)
for(R int i=1;i<=n;++i)
ST[i][j][1]=min(ST[i][j-1][1],ST[i+(1<<(j-1))][j-1][1]);
}
IL int qury_hei(int le,int ri)
{
if(le>ri) swap(le,ri);++le;int lx=lg[ri-le+1];
return min(ST[le][lx][0],ST[ri-(1<<lx)+1][lx][0]);
}
IL int qury_min(int le,int ri)
{
if(le>ri) swap(le,ri);int lx=lg[ri-le+1];
return min(ST[le][lx][1],ST[ri-(1<<lx)+1][lx][1]);
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(have);read(n);
if(have==26)
{
scanf("%s",s+1);key=130;
for(R int i=1;i<=n;++i) num[i]=s[i]-'0'+1;
}
else
{
for(R int i=1;i<=n;++i) read(num[i]),res[i]=num[i];
sort(res+1,res+n+1);key=unique(res+1,res+n+1)-res-1;
for(R int i=1;i<=n;++i) num[i]=lower_bound(res+1,res+key+1,num[i])-res;
// for(R int i=1;i<=n;++i)
// printf("%d%c",num[i],(i==n ? '\n':' '));
// printf("key %d\n",key);
}
get_SA();get_hei();pre();
// printf("SA : ");for(R int i=1;i<=n;++i) printf("%d%c",SA[i],(i==n ? '\n':' '));
// printf("height : ");for(R int i=1;i<=n;++i) printf("%d%c",hei[i],(i==n ? '\n':' '));
for(R int i=1,tail=1;i<=n;++i)
{
while(tail<n&&n-SA[tail]+1<i) ++tail;
//维护单调指针
ans[i]=SA[tail];
int le=tail+1,ri=n,can=-1;
while(le<=ri)
{
int mid=(le+ri)>>1;
if(qury_hei(tail,mid)>=i) can=mid,le=mid+1;
else ri=mid-1;
}
//二分那个位置 用lcp判断是否可以满足贡献出那个串
if(can!=-1) ans[i]=min(ans[i],qury_min(tail,can));
//存在的话 我们就用中间最左端的位置更新
}
for(R int i=1;i<=n;++i) printf("%d%c",ans[i],(i==n ? '\n':' '));
// fclose(stdin);
// fclose(stdout);
return 0;
}
HEOI 2019 RP++
P5108 仰望半月的夜空的更多相关文章
- 洛谷 P5108 仰望半月的夜空 解题报告
P5108 仰望半月的夜空 题目描述 半月的夜空中,寄托了多少人与人之间的思念啊 曦月知道,这些思念会汇集成一个字符串\(S(n = |S|)\) 由于思念汇集的过于复杂,因此曦月希望提炼出所有的思念 ...
- 洛谷P5108 仰望半月的夜空(后缀数组)
题意 题目链接 Sol warning:下面这个做法只有95分,本地拍了1w+组都没找到错误我表示十分无能为力 我们考虑每个串的排名去更新答案,显然排名为\(1\)的后缀的前缀一定是当前长度的字典序最 ...
- P5108 仰望半月的夜空 SAM+线段树覆盖
$ \color{#0066ff}{ 题目描述 }$ 半月的夜空中,寄托了多少人与人之间的思念啊 曦月知道,这些思念会汇集成一个字符串\(S(n = |S|)\) 由于思念汇集的过于复杂,因此曦月希望 ...
- 【Luogu5108】仰望半月的夜空(后缀数组)
[Luogu5108]仰望半月的夜空(后缀数组) 题面 洛谷 题解 实名举报这题在比赛之前还不是这个样子的,还被我用SAM给水过去了 很明显求出\(SA\)之后就是按照\(SA\)的顺序从前往后考虑每 ...
- luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分
仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...
- Luogu 5108 仰望半月的夜空(后缀数组)
如果是要求左端点最大,直接求出SA,找前缀名次最小值就可以了.虽然现在要左端点最小,但我们已经知道了这个字典序最小的串是什么,找到名次数组上的合法区间求最小值即可.我也不知道为什么我会弃掉这个题,可能 ...
- 【LGP5108】仰望半月的夜空
题目 我还会写\(SA\)和 \(ST\)表真是令人感动 发现这是一个思博题 我们开一个指针,标记一下当前合法的字典序最小的后缀排名在哪里,刚开始自然是\(1\) 我们发现这个后缀不能为我们提供\(i ...
- 伙伴们休息啦canvas绘图夜空小屋
HTML5 canvas绘图夜空小屋 伙伴们园友们,夜深了,休息啦,好人好梦... 查看效果:http://hovertree.com/texiao/html5/28/ 效果图如下: 代码如下: &l ...
- HTML5夜空烟花绽放动画效果
模板描述:HTML5夜空烟花绽放动画效果基于HTML5 canvas制作,模拟夜空烟花绽放动画效果,烟花会在夜空打出贺词,有新年快乐.合家幸福.万事如意.心想事成.财源广进等,文字可以自定义,做成各种 ...
随机推荐
- Python学习笔记_读Excel去重
读取一个Excel文件,按照某列关键字,如果有重复则去掉 这里不介绍所有的解决办法,只是列出一个办法. 软件环境: OS:Win10 64位 Python 3.7 测试路径:D:\Work\Pytho ...
- webapi限流框架WebApiThrottle
为了防止网站意外暴增的流量比如活动.秒杀.攻击等,导致整个系统瘫痪,在前后端接口服务处进行流量限制是非常有必要的.本篇主要介绍下Net限流框架WebApiThrottle的使用. WebApiThro ...
- spring与mybatis五种整合方法
1.采用数据映射器(MapperFactoryBean)的方式 不用写mybatis映射文件,采用注解方式提供相应的sql语句和输入参数. (1)Spring配置文件: <!-- 引入jdbc ...
- 实践作业3:白盒测试----第三次小组会DAY8
我们小组于12月11日在东九教学楼召开了会议,小组第二次会议中就讨论了被测系统中风险最高的模块,于是选择管理员的教师添加模块,针对代码展开静态评审.这一次会议,小组主要讨论了应该从哪些方面来测评代码的 ...
- CodeForces 342B Xenia and Spies (水题模拟,贪心)
题意:给定 n 个间谍,m个区间,一个 s,一个f,然后从 s开始传纸条,然后传到 f,然后在每个 t 时间在区间内的不能传,问你最少的时间传过去. 析:这个题,就模拟一下就好,贪心策略,能传就传,找 ...
- eclipse 市场
http://marketplace.eclipse.org/ 如何找工具官网? 举例:UMLet 进入官网以后,下载插件,然后离线安装.
- 20169214 2016-2017-2 《移动平台开发实践》Android程序设计 实验报告
实验四 Android程序设计 课堂练习 实验题目 采用后缀表达式法,设计一个建议计算器,实现+.-.*./四种运算. 代码实现 码云链接 关键代码部分及结果如下: Android程序实验 Andro ...
- 洛谷 P2596 [ZJOI2006]书架 (splay)
题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...
- CodeForces 408E Curious Array(组合数学+差分)
You've got an array consisting of n integers: a[1], a[2], ..., a[n]. Moreover, there are m queries, ...
- SlidesJS基本使用方法和官方文档解释
Slides – 是一个简单的,容易定制和风格化,的jQuery幻灯片插件. Slides提供褪色或幻灯片过渡效果,图像淡入淡出,图像预压,自动生成分页,循环,自动播放的自定义等很多选项. 用Slid ...