BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]
4453: cys就是要拿英魂!
Time Limit: 3 Sec Memory Limit: 128 MB
Submit: 90 Solved: 46
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
5
2 2
3 3
2 5
1 10
2 9
Sample Output
3
3
3
3
数据范围:
1<=|S|<=100000
1<=Q<=100000
1<=l<=r<=|S|
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <set>
using namespace std;
const int N=1e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,Q,l,r;
char s[N];
struct edge{
int v,ne;
}e[N],ed[N];
int cnt,h[N],hd[N],cntd;
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
inline void insd(int u,int v){
int &cnt=cntd,*h=hd;edge *e=ed;
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
struct ques{
int l,id,ne;
}q[N];
int cntq,hq[N];
inline void insq(int r,int l,int id){
int &cnt=cntq,*h=hq;
cnt++;
q[cnt].l=l;q[cnt].ne=h[r];h[r]=cnt;
q[cnt].id=id;
} int sa[N],rnk[N],t1[N],t2[N],height[N],c[N];
bool cmp(int *r,int a,int b,int j){
return a+j<=n&&b+j<=n&&r[a]==r[b]&&r[a+j]==r[b+j];
}
void getSA(int m){
int *r=t1,*k=t2;
for(int i=;i<=n;i++) c[r[i]=s[i]]++;
for(int i=;i<=m;i++) c[i]+=c[i-];
for(int i=n;i>=;i--) sa[c[r[i]]--]=i;
for(int j=;j<=n;j<<=){
int p=;
for(int i=n-j+;i<=n;i++) k[++p]=i;
for(int i=;i<=n;i++) if(sa[i]>j) k[++p]=sa[i]-j; for(int i=;i<=m;i++) c[i]=;
for(int i=;i<=n;i++) c[r[k[i]]]++;
for(int i=;i<=m;i++) c[i]+=c[i-];
for(int i=n;i>=;i--) sa[c[r[k[i]]]--]=k[i]; swap(r,k);p=;r[sa[]]=++p;
for(int i=;i<=n;i++) r[sa[i]]=cmp(k,sa[i],sa[i-],j)?p:++p;
if(p>=n) break;m=p;
}
}
void getHeight(){
for(int i=;i<=n;i++) rnk[sa[i]]=i;
int k=;
for(int i=;i<=n;i++){
if(k) k--;
if(rnk[i]==) continue;
int j=sa[rnk[i]-];
while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
height[rnk[i]]=k;
}
}
int Log[N],Pow[],mn[N][];
void iniST(){
Pow[]=;for(int i=;i<;i++)Pow[i]=Pow[i-]<<;
Log[]=-;for(int i=;i<=n;i++)Log[i]=Log[i/]+;
}
void getST(int mn[N][],int a[]){
for(int i=;i<=n;i++) mn[i][]=a[i];
for(int j=;j<=Log[n];j++)
for(int i=;i+Pow[j]-<=n;i++)
mn[i][j]=min(mn[i][j-],mn[i+Pow[j-]][j-]);
}
int lcp(int x,int y){
x=rnk[x];y=rnk[y];
if(x>y) swap(x,y);x++;
int t=Log[y-x+];
return min(mn[x][t],mn[y-Pow[t]+][t]);
} int vis[N];
set<int> S;
void dfs(int u){//printf("dfs %d\n",u);
vis[u]=;S.erase(u);
for(int i=hd[u];i;i=ed[i].ne)
if(!vis[ed[i].v]) dfs(ed[i].v);
} int st[N],top,ans[N];
void solve(){
for(int r=;r<=n;r++){
S.insert(r);
while(top){
int len=lcp(r,st[top]);
if(s[st[top]+len]>s[r+len]) break;
ins(r+len,st[top]);insd(r,st[top]);top--;
}
st[++top]=r;
for(int i=h[r];i;i=e[i].ne)
if(!vis[e[i].v]) dfs(e[i].v);
for(int i=hq[r];i;i=q[i].ne)
ans[q[i].id]=*S.lower_bound(q[i].l);
}
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%s",s+);
n=strlen(s+);
getSA();getHeight();iniST();getST(mn,height);
Q=read();
for(int i=;i<=Q;i++) l=read(),r=read(),insq(r,l,i);
solve();
for(int i=;i<=Q;i++) printf("%d\n",ans[i]);
}
BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]的更多相关文章
- bzoj千题计划313:bzoj3879: SvT(后缀数组+st表+单调栈)
https://www.lydsy.com/JudgeOnline/problem.php?id=3879 把所有的后缀取出,按rank排序 求出相邻两个后缀的lcp 每个后缀对答案的贡献就是 与在它 ...
- bzoj千题计划314:bzoj3238: [Ahoi2013]差异(后缀数组+st表+单调栈)
https://www.lydsy.com/JudgeOnline/problem.php?id=3238 跟 bzoj3879 差不多 #include<cstdio> #include ...
- SPOJ 687 Repeats(后缀数组+ST表)
[题目链接] http://www.spoj.com/problems/REPEATS/en/ [题目大意] 求重复次数最多的连续重复子串的长度. [题解] 考虑错位匹配,设重复部分长度为l,记s[i ...
- POJ 3693 Maximum repetition substring(后缀数组+ST表)
[题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...
- BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay
BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...
- UVA10829 L-Gap Substrings(后缀数组+ST表)
后缀数组+ST表. 代填的坑. \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long using namespace ...
- 【bzoj3879】SvT 后缀数组+倍增RMQ+单调栈
题目描述 (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始位置来表示), ...
- BZOJ.4453.cys就是要拿英魂!(后缀数组 单调栈)
BZOJ 求字典序最大,容易想到对原串建后缀数组求\(rk\). 假设当前区间是\([l,r]\),对于在\([l,r]\)中的两个后缀\(i,j\)(\(i<j\)),显然我们不能直接比较\( ...
- bzoj 4453 cys就是要拿英魂! —— 后缀数组+单调栈+set
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4453 这种问题...一般先把询问离线,排序: 区间对后缀排名的影响在于一些排名大而位置靠后的 ...
随机推荐
- 菜鸟学Struts2——Results
在对Struts2的Action学习之后,对Struts2的Result进行学习.主要对Struts2文档Guides中的Results分支进行学习,如下图: 1.Result Types(Resul ...
- 多线程的通信和同步(Java并发编程的艺术--笔记)
1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递. 2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...
- css-父标签中的子标签默认位置
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(64)-WebApi与Unity注入
系列目录 前言: 有时候我们系统需要开放数据给手机App端或其他移动设备,不得不说Asp.net WebApi是目前首选 本节记录Asp.net MVC WebApi怎么利用Unity注入.系列开头已 ...
- 8、Struts2 运行流程分析
1.流程分析: 请求发送给 StrutsPrepareAndExecuteFilter StrutsPrepareAndExecuteFilter 询问 ActionMapper: 该请求是否是一个 ...
- kafka配置与使用实例
kafka作为消息队列,在与netty.多线程配合使用时,可以达到高效的消息队列
- WebGIS中等值面展示的相关方案简析
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...
- 代码的坏味道(20)——过度耦合的消息链(Message Chains)
坏味道--过度耦合的消息链(Message Chains) 特征 消息链的形式类似于:obj.getA().getB().getC(). 问题原因 如果你看到用户向一个对象请求另一个对象,然后再向后者 ...
- 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)
建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...
- C++ 事件驱动型银行排队模拟
最近重拾之前半途而废的C++,恰好看到了<C++ 实现银行排队服务模拟>,但是没有实验楼的会员,看不到具体的实现,正好用来作为练习. 模拟的是银行的排队叫号系统,所有顾客以先来后到的顺序在 ...