Description

佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物。生日礼物放在一个神奇的箱子中。箱子外边写了
一个长为n的字符串s,和m个问题。佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职加薪,出任CE
O,嫁给高富帅,走上人生巅峰。每个问题均有a,b,c,d四个参数,问你子串s[a..b]的所有子串和s[c..d]的最长公
共前缀的长度的最大值是多少?佳媛姐姐并不擅长做这样的问题,所以她向你求助,你该如何帮助她呢?

Input

输入的第一行有两个正整数n,m,分别表示字符串的长度和询问的个数。接下来一行是一个长为n的字符串。接下来
m行,每行有4个数a,b,c,d,表示询问s[a..b]的所有子串和s[c..d]的最长公共前缀的最大值。1<=n,m<=100,000,
字符串中仅有小写英文字母,a<=b,c<=d,1<=a,b,c,d<=n
 

Output

对于每一次询问,输出答案。

Sample Input

5 5
aaaaa
1 1 1 5
1 5 1 1
2 3 2 3
2 4 2 3
2 3 2 4

Sample Output

1
1
2
2
2
 
考虑将串逆序后使用后缀自动机来做,对于每个询问我们可以二分一下答案len,然后倍增到SAM上的对应节点,这是我们发现只要判断该节点的right集中是否包含[a,b-len+1]中的元素即可。这个用棵线段树合并什么的东西预处理一下每个节点的right集就好了,时间复杂度为O(Nlog^2N)。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=200010;
const int maxnode=4000010;
int n,m,root[maxn],pos[maxn],c[maxn],od[maxn];
int ls[maxnode],rs[maxnode],ToT;
int to[maxn][26],anc[maxn][20],l[maxn],fa[maxn],cnt=1,last=1;
void insert(int& y,int l,int r,int p) {
y=++ToT;if(l==r) return;int mid=l+r>>1;
if(p<=mid) insert(ls[y],l,mid,p);
else insert(rs[y],mid+1,r,p);
}
int merge(int x,int y) {
if(!x) return y;
if(!y) return x;
int z=++ToT;
ls[z]=merge(ls[x],ls[y]);
rs[z]=merge(rs[x],rs[y]);
return z;
}
int query(int x,int l,int r,int ql,int qr) {
if(!x) return 0;
if(ql<=l&&r<=qr) return 1;
int mid=l+r>>1;
if(ql<=mid&&query(ls[x],l,mid,ql,qr)) return 1;
if(qr>mid&&query(rs[x],mid+1,r,ql,qr)) return 1;
}
void extend(int c,int val) {
int p=last,q,np,nq;l[last=np=++cnt]=l[p]+1;
insert(root[np],1,n,val);pos[val]=np;
for(;!to[p][c];p=fa[p]) to[p][c]=np;
if(!p) fa[np]=1;
else {
q=to[p][c];
if(l[p]+1==l[q]) fa[np]=q;
else {
l[nq=++cnt]=l[p]+1;
fa[nq]=fa[q];fa[q]=fa[np]=nq;
memcpy(to[nq],to[q],sizeof(to[q]));
for(;to[p][c]==q;p=fa[p]) to[p][c]=nq;
}
}
}
char str[maxn];
int check(int x,int a,int b,int p) {
dwn(i,19,0) if(x<=l[anc[p][i]]) p=anc[p][i];
return query(root[p],1,n,a,b-x+1);
}
int main() {
n=read();m=read();
scanf("%s",str+1);
dwn(i,n,1) extend(str[i]-'a',i);
rep(i,1,cnt) c[l[i]]++;
rep(i,1,n) c[i]+=c[i-1];
dwn(i,cnt,1) od[c[l[i]]--]=i;
dwn(i,cnt,1) root[fa[od[i]]]=merge(root[fa[od[i]]],root[od[i]]);
rep(i,1,cnt) {
int x=od[i];anc[x][0]=fa[x];
rep(j,1,19) anc[x][j]=anc[anc[x][j-1]][j-1];
}
while(m--) {
int a=read(),b=read(),x=read(),y=read();
int l=0,r=min(y-x+1,b-a+1)+1,mid;
while(l+1<r) if(check(mid=l+r>>1,a,b,pos[x])) l=mid; else r=mid;
printf("%d\n",l);
}
return 0;
}

  

BZOJ4556: [Tjoi2016&Heoi2016]字符串的更多相关文章

  1. [BZOJ4556][TJOI2016&&HEOI2016]字符串(二分答案+后缀数组+RMQ+主席树)

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1360  Solved: 545[S ...

  2. Bzoj4556: [Tjoi2016&Heoi2016]字符串 后缀数组

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 169  Solved: 87[Sub ...

  3. [BZOJ4556][Tjoi2016&Heoi2016]字符串 后缀数组+主席树

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MB Description 佳媛姐姐过生日的时候,她的小 ...

  4. [BZOJ4556][Tjoi2016&Heoi2016]字符串 主席树+二分+倍增+后缀自动机

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1215  Solved: 484[S ...

  5. BZOJ4556 [Tjoi2016&Heoi2016]字符串 SA ST表 二分答案 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4556.html 题目传送门 - BZOJ4556 题意 给定一个长度为 $n$ 的字符串 $s$ . ...

  6. 2019.02.27 bzoj4556: [Tjoi2016&Heoi2016]字符串(二分答案+sam+线段树合并)

    传送门 题意:给一个字符串SSS. 有mmm次询问,每次给四个参数a,b,c,da,b,c,da,b,c,d,问s[a...b]s[a...b]s[a...b]的所有子串和s[x...y]s[x... ...

  7. bzoj4556: [Tjoi2016&Heoi2016]字符串 (后缀数组加主席树)

    题目是给出一个字符串,每次询问一个区间[a,b]中所有的子串和另一个区间[c,d]的lcp最大值,首先求出后缀数组,对于lcp的最大值肯定是rank[c]的前驱和后继,但是对于这个题会出现问题,就是题 ...

  8. BZOJ4556 Tjoi2016&Heoi2016 字符串【后缀自动机+倍增+线段树合并】

    Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开 ...

  9. BZOJ4556 [Tjoi2016&Heoi2016]字符串 【后缀数组 + 主席树 + 二分 + ST表】

    题目 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职 ...

随机推荐

  1. hdu 5288 数学 ****

    给一个序列 定义函数f(l ,r) 为区间[l ,r] 中 的数ai不是在这个区间其他任意数aj的倍数 求所有f(l,r)之和 通过预处理,记录 a[i] 的左右边界(所谓的左右边界时 在从 a[i] ...

  2. 不通过App Store实现ios应用分发下载安装

    最近公司的项目准备着手宣传工作了,宣传手册上要印制App的下载地址二维码,但是客户端应用还未上线,需要一种临时的方案解决应用分发下载问题,通常ios应用必须通过苹果应用商店才能下载安装,但是也可以看到 ...

  3. DateTime时间格式

    DateTime dt = DateTime.Now; Label1.Text = dt.ToString();//2005-11-5 13:21:25 Label2.Text = dt.ToFile ...

  4. How to use Ajax on Visualforce page on Salesforce platform

    Just use Ajax pattern to call object data from server on visualforce page. Following is the Asynchro ...

  5. HDU 1561 The more, The Better 树形DP

    The more, The Better Problem Description   ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M ...

  6. HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. MFC 丢失MSVCR120D.dll 丢失mfc120ud.dll

  8. Java可变参数讲解

    如果实现的多个方法,这些方法里面逻辑基本相同,唯一不同的是传递的参数的个数,可以使用可变参数可变参数的定义方法 数据类型...数组的名称,这个数组存储传递过来的参数,类似JavaScript注意点:  ...

  9. Matlab 查看变量信息who whos命令

  10. express-9 Handlebars模板引擎(2)

    视图和布局 视图通常表现为网站上的各个页面(它也可以表现为页面中AJAX局部加载的内容,或一封电子邮件,或页面上的任何东西).默认情况下,Express会在views子目录中查找视图.布局是一种特殊的 ...