Luogu 5108 仰望半月的夜空(后缀数组)
如果是要求左端点最大,直接求出SA,找前缀名次最小值就可以了。虽然现在要左端点最小,但我们已经知道了这个字典序最小的串是什么,找到名次数组上的合法区间求最小值即可。我也不知道为什么我会弃掉这个题,可能太久没写字符串了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,a[N],b[N],sa[N],sa2[N],rk[N<<],tmp[N<<],cnt[N],h[N],f[N][],g[N][],lg2[N],ans[N],stk[N],top;
void make()
{
int m=;
for (int i=;i<=n;i++) cnt[rk[i]=a[i]]++,m=max(m,a[i]);
for (int i=;i<=m;i++) cnt[i]+=cnt[i-];
for (int i=n;i>=;i--) sa[cnt[rk[i]]--]=i;
for (int k=;k<=n;k<<=)
{
int p=;
for (int i=n-k+;i<=n;i++) sa2[++p]=i;
for (int i=;i<=n;i++) if (sa[i]>k) sa2[++p]=sa[i]-k;
memset(cnt,,sizeof(cnt));
for (int i=;i<=n;i++) cnt[rk[i]]++;
for (int i=;i<=m;i++) cnt[i]+=cnt[i-];
for (int i=n;i>=;i--) sa[cnt[rk[sa2[i]]]--]=sa2[i];
memcpy(tmp,rk,sizeof(rk));
p=rk[sa[]]=;
for (int i=;i<=n;i++)
{
if (tmp[sa[i]]!=tmp[sa[i-]]||tmp[sa[i]+k]!=tmp[sa[i-]+k]) p++;
rk[sa[i]]=p;
}
if (p==n) break;
m=p;
}
for (int i=;i<=n;i++)
{
h[i]=max(h[i-]-,);
while (a[i+h[i]]==a[sa[rk[i]-]+h[i]]) h[i]++;
}
for (int i=;i<=n;i++) f[i][]=h[sa[i]],g[i][]=sa[i];
lg2[]=;
for (int i=;i<=n;i++)
{
lg2[i]=lg2[i-];
if ((<<lg2[i])<=i) lg2[i]++;
}
for (int j=;j<;j++)
for (int i=;i<=n;i++)
f[i][j]=min(f[i][j-],f[min(n,i+(<<j-))][j-]),
g[i][j]=min(g[i][j-],g[min(n,i+(<<j-))][j-]);
}
int query(int x,int y)
{
if (x>y) swap(x,y);
x++;if (x>y) return N;
return min(f[x][lg2[y-x+]],f[y-(<<lg2[y-x+])+][lg2[y-x+]]);
}
int query2(int x,int y)
{
return min(g[x][lg2[y-x+]],g[y-(<<lg2[y-x+])+][lg2[y-x+]]);
}
int find(int x,int len)
{
int l=,r=x,u;
while (l<=r)
{
int mid=l+r>>;
if (query(mid,x)>=len) u=mid,r=mid-;
else l=mid+;
}
l=x,r=n;int v;
while (l<=r)
{
int mid=l+r>>;
if (query(mid,x)>=len) v=mid,l=mid+;
else r=mid-;
}
return query2(u,v);
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
m=read(),n=read();
if (m==) for (int i=;i<=n;i++) a[i]=getc()-'a';
else for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=n;i++) b[i]=a[i];
sort(b+,b+n+);int t=unique(b+,b+n+)-b-;
for (int i=;i<=n;i++) a[i]=lower_bound(b+,b+t+,a[i])-b;
make();
int p=n+;
for (int i=;i<=n;i++)
{
p=min(p,rk[i]);
ans[n-i+]=find(p,n-i+);
}
for (int i=;i<=n;i++) printf("%d ",ans[i]);
return ;
}
Luogu 5108 仰望半月的夜空(后缀数组)的更多相关文章
- 洛谷P5108 仰望半月的夜空(后缀数组)
题意 题目链接 Sol warning:下面这个做法只有95分,本地拍了1w+组都没找到错误我表示十分无能为力 我们考虑每个串的排名去更新答案,显然排名为\(1\)的后缀的前缀一定是当前长度的字典序最 ...
- 【Luogu5108】仰望半月的夜空(后缀数组)
[Luogu5108]仰望半月的夜空(后缀数组) 题面 洛谷 题解 实名举报这题在比赛之前还不是这个样子的,还被我用SAM给水过去了 很明显求出\(SA\)之后就是按照\(SA\)的顺序从前往后考虑每 ...
- luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分
仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...
- luogu 2463 [SDOI2008]Sandy的卡片 kmp || 后缀数组 n个串的最长公共子串
题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwe ...
- 【Luogu】P3809后缀排序(后缀数组模板)
题目链接 今天终于学会了后缀数组模板qwq 不过只会模板emmmm 首先我们有一本蓝书emmmmmm 然后看到蓝书221页代码之后我就看不懂了 于是请出rqy rqy: 一开始那是个对单个字符排序的操 ...
- LUOGU P2408 不同子串个数(后缀数组)
传送门 解题思路 后缀数组求本质不同串的裸题.\(ans=\dfrac{n(n+1)}{2} -\sum height[i]\). 代码 #include<iostream> #inclu ...
- 洛谷P4051 [JSOI2007]字符加密 后缀数组
题目链接:https://www.luogu.org/problemnew/show/P4051 思路:我们联想求后缀数组sa的过程,发现我们在求y数组的时候(第二关键字,下标为第二关键字的排位,值为 ...
- [笔记]后缀数组SA
参考资料这次是真抄的: 1.后缀数组详解 2.后缀数组-学习笔记 3.后缀数组--处理字符串的有力工具 定义 \(SA\)排名为\(i\)的后缀的位置 \(rk\)位置为\(i\)的后缀的排名 \(t ...
- BZOJ 4556: [Tjoi2016&Heoi2016]字符串(后缀数组 + 二分答案 + 主席树 + ST表 or 后缀数组 + 暴力)
题意 一个长为 \(n\) 的字符串 \(s\),和 \(m\) 个询问.每次询问有 \(4\) 个参数分别为 \(a,b,c,d\). 要你告诉它 \(s[a...b]\) 中的所有子串 和 \(s ...
随机推荐
- JMeter的__threadGroupName使用注意事项
JMeter从4.1版本开始引入了一个新函数"${__threadGroupName}",这个函数的作用是返回当前线程组的名字.${__threadGroupName}的用途也较为 ...
- Appium+python的单元测试框架unittest(1)(转)
unittest为python语言自带的单元测试框架,python把unittest封装为一个标准模块封装在python开发包中.unittest中常用的类有:unittest.TestCase.un ...
- Jmeter+ant+jenkins接口自动化测试 平台搭建(二)
一.依赖文件配置 1.在ant目录C:\apache-ant-1.10.5下新建一个demo文件夹,并将jmeter测试脚本放在该文件夹中 2.将\apache-jmeter-3.3\extras下面 ...
- jQuery的$ .ajax防止重复提交的方法
没啥说的直接贴代码,很简单: 第一种方式:的onclick点击事件类型 <SCRIPT> function member_del(obj,id){ var lock = false; // ...
- JavaWeb-Servlet-Tomcat
Servlet就是运行在服务器上的Java类.Servlet容器为javaweb应用提供运行时环境,负责管理Servlet和JSP的生命周期,以及管理它们的共享数据. Servlet容器软件——Tom ...
- 04-matplotlib-柱形图
import numpy as np import matplotlib.pyplot as plt # 柱形图 # 例一 N =5 y = [15,28,10,30,25] index = np.a ...
- ossec代理
代理端 OSSEC有两种代理端:可安装的代理端和哑代理端(免安装).可安装的代理端被安装在主机上,通过OSSEC的加密协议将主机的信息发送到OSSEC服务器.亚代理端则不需在远端主机进行安装.他作为O ...
- sql语句(Mysql数据库)
Mysql数据库的sql语句: 一.基本操作 1.连接数据库 mysql -uroot -proot -hlocalhost -P3306 (-u表示用户名,-p密码,-h主机,-P端口号) 2.选择 ...
- JavaScript设计模式-----模板方法模式
模板方法模式是一种只需要使用继承就可以实现的非常简单点的模式. 模板方法模式有两部分组成,第一部分是抽象父类,第二部分是具体的实现子类.通常在抽象父类中封装了子类的算法框架,包括实现 一些公共方法以及 ...
- C++多态深入分析!
以下分析是基于VS2010的.以后会使用G++分析看看G++如何处理多态! // polymorphic_test.cpp : 定义控制台应用程序的入口点. // /** 特别注意:实现C++多态,除 ...