如果是要求左端点最大,直接求出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<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}
int n,m,a[N],b[N],sa[N],sa2[N],rk[N<<1],tmp[N<<1],cnt[N],h[N],f[N][20],g[N][20],lg2[N],ans[N],stk[N],top;
void make()
{int m=0;for (int i=1;i<=n;i++) cnt[rk[i]=a[i]]++,m=max(m,a[i]);for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1];for (int i=n;i>=1;i--) sa[cnt[rk[i]]--]=i;for (int k=1;k<=n;k<<=1){int p=0;for (int i=n-k+1;i<=n;i++) sa2[++p]=i;for (int i=1;i<=n;i++) if (sa[i]>k) sa2[++p]=sa[i]-k;memset(cnt,0,sizeof(cnt));for (int i=1;i<=n;i++) cnt[rk[i]]++;for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1];for (int i=n;i>=1;i--) sa[cnt[rk[sa2[i]]]--]=sa2[i];memcpy(tmp,rk,sizeof(rk));p=rk[sa[1]]=1;for (int i=2;i<=n;i++){if (tmp[sa[i]]!=tmp[sa[i-1]]||tmp[sa[i]+k]!=tmp[sa[i-1]+k]) p++;rk[sa[i]]=p;}if (p==n) break;m=p;}for (int i=1;i<=n;i++){h[i]=max(h[i-1]-1,0);while (a[i+h[i]]==a[sa[rk[i]-1]+h[i]]) h[i]++;}for (int i=1;i<=n;i++) f[i][0]=h[sa[i]],g[i][0]=sa[i];lg2[1]=0;for (int i=2;i<=n;i++){lg2[i]=lg2[i-1];if ((2<<lg2[i])<=i) lg2[i]++;}for (int j=1;j<20;j++)for (int i=1;i<=n;i++)f[i][j]=min(f[i][j-1],f[min(n,i+(1<<j-1))][j-1]),g[i][j]=min(g[i][j-1],g[min(n,i+(1<<j-1))][j-1]);
}
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+1]],f[y-(1<<lg2[y-x+1])+1][lg2[y-x+1]]);
}
int query2(int x,int y)
{return min(g[x][lg2[y-x+1]],g[y-(1<<lg2[y-x+1])+1][lg2[y-x+1]]);
}
int find(int x,int len)
{int l=1,r=x,u;while (l<=r){int mid=l+r>>1;if (query(mid,x)>=len) u=mid,r=mid-1;else l=mid+1;}l=x,r=n;int v;while (l<=r){int mid=l+r>>1;if (query(mid,x)>=len) v=mid,l=mid+1;else r=mid-1;}return query2(u,v);
}
signed main()
{
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);const char LL[]="%I64d\n";
#elseconst char LL[]="%lld\n";
#endifm=read(),n=read();if (m==26) for (int i=1;i<=n;i++) a[i]=getc()-'a';else for (int i=1;i<=n;i++) a[i]=read();for (int i=1;i<=n;i++) b[i]=a[i];sort(b+1,b+n+1);int t=unique(b+1,b+n+1)-b-1;for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+t+1,a[i])-b;make();int p=n+1;for (int i=1;i<=n;i++){p=min(p,rk[i]);ans[n-i+1]=find(p,n-i+1);}for (int i=1;i<=n;i++) printf("%d ",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/Gloid/p/10128863.html

Luogu 5108 仰望半月的夜空(后缀数组)相关推荐

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

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

  2. bzoj5108 数据_【Luogu5108】仰望半月的夜空(后缀数组)

    [Luogu5108]仰望半月的夜空(后缀数组) 题面 题解 实名举报这题在比赛之前还不是这个样子的,还被我用SAM给水过去了 很明显求出$SA$之后就是按照$SA$的顺序从前往后考虑每一个长度,这样 ...

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

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

  4. UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组、ST表)

    UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组.ST表) 连NOI Day1T1都不会做...看了题解都写不出来还要抄Claris的代码.. 题 ...

  5. 【背板子-后缀数组】BZOJ4199 BZOJ4650 LGP5108 CF504E

    [前言] 后缀数组一直是我没有背的板子来着. 强行背了下来. adjust这个函数丢不掉了. [题目] BZOJ4199 [NOI2015] 品酒大会 BZOJ 按heightheightheight ...

  6. 洛谷P3809 后缀数组模板

    题目:https://www.luogu.org/problemnew/show/P3809 刚学了后缀数组,看人家手写演示了半天,大概明白了过程,但完全写不出来代码: 于是借鉴了许多,不过都差不多, ...

  7. 算法学习:后缀数组(SA)

    [参考博客] https://xminh.github.io/2018/02/27/%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84-%E6%9C%80%E8%AF%A6%E7 ...

  8. c++ 字符串数组长度排序_数组 | 后缀数组的求法及应用

    作者:Andy__lee 链接:https://blog.nowcoder.net/n/6b4a93e186ed4a358321de6a7c3b4f19 来源:牛客网 定义 维基百科 - 后缀数组 让 ...

  9. 洛谷P2178 [NOI2015]品酒大会 后缀数组+单调栈

    P2178 [NOI2015]品酒大会 题目链接 https://www.luogu.org/problemnew/show/P2178 题目描述 一年一度的"幻影阁夏日品酒大会" ...

最新文章

  1. python序列类型包括哪三种映射类型_python序列类型包括哪三种_后端开发
  2. mybatis多条件查询
  3. 【C#控件详解】对话框类控件(打开文件,保存文件,选择字体和颜色)
  4. 了解IT行业前沿应用,关注数据与算法之美
  5. vim:复制复制字符到vim的命令行窗口的4种方法
  6. 数据治理的坑你遇到过几个?
  7. 前端程序员简历模板整理和下载
  8. CentOS 8 下载安装stress实际操作以及实际应用,以及遇到的问题
  9. 推荐系统系列——经典推荐算法
  10. ADS2015导入飞思卡尔元器件模型 安装DesignKit
  11. Python 日期格式总结
  12. c语言课程成绩分析报告范文,c语言课程分析报告题目.doc
  13. IOS开发教程第一季之02UI进阶day4合并IOS学习015--Segue小专题、沙盒存储小专题、归档/解档、TabBarController、App主流UI框架结构
  14. created和mounted时期请求API的区别
  15. hive取当前周的周一
  16. Arduino uno 折腾笔记-uno 变 键盘
  17. [Android Pro] Android TypedValue.applyDimension()的用法
  18. 根据三角形的三条边长(长、中、短三条边),来判断三角形类型。注意: 1.一个三角形的边长应该都为正数 2.一个三角形的边长都应该满足三角形条件:两边之和大于第三边 如果有两边的
  19. VC获取EXCEL 表格的总行数
  20. 项目之相对路径、绝对路径, 路径问题

热门文章

  1. 2022-2027年中国医疗服务机器人行业市场调研及未来发展趋势预测报告
  2. 市场营销学4——市场调研与预测
  3. 以小饭桌网站为例介绍抓取动态网页的数据【python爬虫入门进阶】(12)
  4. ElasticSearch--分片和副本--原理
  5. 超平面,半空间,多面体,单纯形定义与解析
  6. 智慧图书馆,RFID技术在图书借还,图书防盗中的应用优势
  7. From表单的属性action和method
  8. 什么是物联网,与传感网之间,有什么区别
  9. 数据指标体系:指标好坏评价标准
  10. linux 的手机操作系统下载地址,Linux系统运维之下载Linux操作系统地址