二分答案,(具体可见http://blog.csdn.net/neither_nor/article/details/51669114),然后就是判定问题,sa和sam都可以做,用sam写了一下,先用sam建后缀树,然后用主席树维护right集合就好了,每次判断把对应节点倍增到深度为mid的点,然后看一下他的子树里有没有right在对应区间的点就好了。

(前几天用sa写了一下,bz能A,洛谷一直WA,有空重构吧。。。)

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=,maxm=;
int a,b,c,d,t,pos[maxn],cnt=,cur,fa[maxn],ch[maxn][],dis[maxn],n,m,tot;
char s[maxn];
int add(int c,int p){
cur=++cnt;dis[cur]=dis[p]+;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=cur;
if(!p)fa[cur]=;
else{
int q=ch[p][c];
if(dis[q]==dis[p]+)fa[cur]=q;
else{
int nt=++cnt;dis[nt]=dis[p]+;
memcpy(ch[nt],ch[q],sizeof(ch[]));
fa[nt]=fa[q];fa[q]=fa[cur]=nt;
for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nt;
}
}
return cur;
}
vector<int>tong[maxn];
int root[maxn],siz[maxn],tim,last[maxn*],pre[maxn*],other[maxn*],f[maxn][],dfn[maxn],from[maxn];
void insert(int x,int y){++t;pre[t]=last[x];last[x]=t;other[t]=y;}
void dfs(int x){
siz[x]=;dfn[x]=++tim;from[tim]=x;
for(int i=last[x];i;i=pre[i]){
int v=other[i];
f[v][]=x;dfs(v);
siz[x]+=siz[v];
}
}
int jump(int x,int y){
for(int i=;i>=;--i){
if(dis[f[x][i]]>=y)x=f[x][i];
}
return x;
}
struct node{
int l,r,v;
}tr[maxm];
void build(int pos,int l,int r,int &x){
++tot;tr[tot]=tr[x];x=tot;++tr[x].v;
if(l==r)return;
int mid=l+r>>;
if(pos<=mid)build(pos,l,mid,tr[x].l);
else build(pos,mid+,r,tr[x].r);
}
int qs(int i,int j,int l,int r,int L,int R){
if(r<L||l>R||r<l)return ;
if(l>=L&&r<=R)return tr[j].v-tr[i].v;
int mid=l+r>>;
return qs(tr[i].l,tr[j].l,l,mid,L,R)+qs(tr[i].r,tr[j].r,mid+,r,L,R);
}
int pd(int mid){
int op=jump(pos[c],mid);
return qs(root[dfn[op]-],root[dfn[op]+siz[op]-],,n,a,b-mid+);
}
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int tmp=;
cin>>n>>m;
scanf("%s",s+);
for(int i=n;i>=;--i){
tmp=add(s[i]-'a',tmp);
pos[i]=tmp;
tong[pos[i]].push_back(i);
}
for(int i=;i<=cnt;++i)insert(fa[i],i);dfs();
for(int j=;j<=;++j)
for(int i=;i<=cnt;++i){
f[i][j]=f[f[i][j-]][j-];
}
for(int i=;i<=tim;++i){
int siz=tong[from[i]].size();root[i]=root[i-];
for(int j=;j<siz;++j){
build(tong[from[i]][j],,n,root[i]);
}
}
for(int i=;i<=m;++i){
scanf("%d%d%d%d",&a,&b,&c,&d);
int l=,r=min(d-c+,b-a+),ans=;
while(l<=r){
int mid=l+r>>;
if(pd(mid))ans=mid,l=mid+;
else r=mid-;
}
printf("%d\n",ans);
}
//fclose(stdin);
//fclose(stdout);
//system("pause");
return ;
}
/*
50 1
pnzogoobycwczqfrbylxuwkgmnzlekbcakviijcrjahthagkcn
20 47 8 50
*/

bzoj4556(sam)的更多相关文章

  1. 字符串(tjoi2016,heoi2016,bzoj4556)(sam(后缀自动机)+线段树合并+倍增+二分答案)

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

  2. 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... ...

  3. SAM初探

    SAM,即Suffix Automaton,后缀自动机. 关于字符串有很多玩法,有很多算法都是围绕字符串展开的.为什么?我的理解是:相较于数字组成的序列,字母组成的序列中每个单位上元素的个数是有限的. ...

  4. bzoj4199:NOI2015D2T2品酒大会(SAM版)

    SAM感觉写起来比SA更直观(?) #include <iostream> #include <cstdio> #include <cstring> #includ ...

  5. SAM/BAM文件处理

    当测序得到的fastq文件map到基因组之后,我们通常会得到一个sam或者bam为扩展名的文件.SAM的全称是sequence alignment/map format.而BAM就是SAM的二进制文件 ...

  6. hihocoder SAM基础概念

    后缀自动机一·基本概念 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:今天我们来学习一个强大的字符串处理工具:后缀自动机(Suffix Automaton,简称 ...

  7. BZOJ4556: [Tjoi2016&Heoi2016]字符串

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

  8. bam/sam格式说明

    在SAM输出的结果中每一行都包括十二项通过Tab分隔,从左到右分别是: 1 序列的名字(Read的名字) 2 概括出一个合适的标记,各个数字分别代表 1     序列是一对序列中的一个 2     比 ...

  9. mismatch位置(MD tag)- sam/bam格式解读进阶

    这算是第二讲了,前面一讲是:Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶 MD是mismatch位置的字符串的表示形式,貌似在call SNP和indel的时候会用 ...

随机推荐

  1. day39数据库之基本数据类型

    数据库之数据类型1.数据存储引擎 一个功能的核心部分,回到mysql        核心功能是存储数据  涉及到存储数据的代码 就称之为存储引擎        根据不同的需求 也有着不同的引擎分类 不 ...

  2. 谈谈线上CPU100%排查套路

    知识点总结 ---------------------------------------------------------------------------------------------- ...

  3. http stream

    http stream 博客分类: http://canofy.iteye.com/blog/2097876 j2EE   StringBuilder sb = new StringBuilder() ...

  4. leetcode94

    class Solution { public: vector<int> V; void inOrder(TreeNode* node) { if (node != NULL) { if ...

  5. django 数据库查询的几个知识点

    django查询db过程中遇到的几个问题: 1. 数据库切换,用using products = models.TProductCredit.objects.using(') 2.查询结构集是Quer ...

  6. [Shell]Bash变量:自定义变量 & 环境变量 & 位置参数变量 & 预定义变量

    --------------------------------------------------------------------------------- 变量是计算机内存的单元,其中存放的值 ...

  7. request设置cookies

    mycookie = { "PHPSESSID":"56v9clgo1kdfo3q5q8ck0aaaaa" } request.get(url,cookies ...

  8. 2018面向对象程序设计(Java)第18周学习指导及要求

    2018面向对象程序设计(Java) 第18周学习指导及要求(2018.12.27-2018.12.30)   学习目标 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设 ...

  9. Python设计模式 - UML - 总览

    说到设计模式就不得不涉及建模思想,说到建模思想自然而然会应用UML,目前业界开源的UML工具很多,用起来也非常便捷.近几年来随着软件应用领域开发模式转向快速迭代试错,UML在敏捷开发,尤其是web及m ...

  10. 第一个只出现一次的字符字符(python)

    题目描述 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).   # -*- codin ...