如果是要求左端点最大,直接求出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 ;
}

最新文章

  1. 抓取百万知乎用户信息之HttpHelper的迭代之路
  2. Mac/IOS/linux获取当前时间包含微秒毫秒的代码
  3. 【grunt第一弹】30分钟学会使用grunt打包前端代码
  4. node基础11:接受参数
  5. polyfill之javascript函数的兼容写法——Array篇
  6. 【HDU 3401 Trade】 单调队列优化dp
  7. Windows2012中Python2.7.11+Python3.4.4+Pycharm
  8. codeigniter(ci)在nginx下返回404的处理方法即codeigniter在nginx下配置方法
  9. Vuex原来可以这样上手
  10. 1034. Head of a Gang
  11. MySQL错误2003:Can&#39;t connect to MySQL server (10060)
  12. Angular4 - Can&#39;t bind to &#39;ngModel&#39; since it isn&#39;t a known property of &#39;input&#39;.
  13. Multimodal —— 看图说话(Image Caption)任务的论文笔记(二)引入attention机制
  14. struts学习总结
  15. 【puppeteer】前端自动化初探(一)
  16. 集合之ArrayList(含JDK1.8源码分析)
  17. Individual P1: Summary
  18. jquery 元素选择器
  19. canvas打字效果
  20. [Winform]缓存处理

热门文章

  1. CSS过渡动画之transition
  2. REVIT个人学习笔记——1.简介及熟悉界面
  3. gith命令行使用之上传和删除
  4. Unity编辑器扩展 Chapter7--使用ScriptableObject持久化存储数据
  5. redis-4.0.2
  6. Analysis 图标分析 - loadrunner
  7. C#中字符串 &quot;驻留&quot;与Lock(转载)
  8. TCP协议数据包及攻击分析
  9. Mongodb For Mac OSX &amp;&amp; 登录验证
  10. 原生JavaScript实现的贪吃蛇