bzoj4556(sam)
二分答案,(具体可见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)的更多相关文章
- 字符串(tjoi2016,heoi2016,bzoj4556)(sam(后缀自动机)+线段树合并+倍增+二分答案)
佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为\(n\)的字符串\(s\),和\(m\)个问题.佳媛姐姐必须正确回答这\(m\)个问题, ...
- 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... ...
- SAM初探
SAM,即Suffix Automaton,后缀自动机. 关于字符串有很多玩法,有很多算法都是围绕字符串展开的.为什么?我的理解是:相较于数字组成的序列,字母组成的序列中每个单位上元素的个数是有限的. ...
- bzoj4199:NOI2015D2T2品酒大会(SAM版)
SAM感觉写起来比SA更直观(?) #include <iostream> #include <cstdio> #include <cstring> #includ ...
- SAM/BAM文件处理
当测序得到的fastq文件map到基因组之后,我们通常会得到一个sam或者bam为扩展名的文件.SAM的全称是sequence alignment/map format.而BAM就是SAM的二进制文件 ...
- hihocoder SAM基础概念
后缀自动机一·基本概念 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:今天我们来学习一个强大的字符串处理工具:后缀自动机(Suffix Automaton,简称 ...
- BZOJ4556: [Tjoi2016&Heoi2016]字符串
Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开 ...
- bam/sam格式说明
在SAM输出的结果中每一行都包括十二项通过Tab分隔,从左到右分别是: 1 序列的名字(Read的名字) 2 概括出一个合适的标记,各个数字分别代表 1 序列是一对序列中的一个 2 比 ...
- mismatch位置(MD tag)- sam/bam格式解读进阶
这算是第二讲了,前面一讲是:Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶 MD是mismatch位置的字符串的表示形式,貌似在call SNP和indel的时候会用 ...
随机推荐
- synchronized和lock以及synchronized和volatile的区别
synchronized和volatile区别synochronizd和volatile关键字区别: 1. volatile关键字解决的是变量在多个线程之间的可见性:而sychronized关键字解决 ...
- python下selenium自动化测试自我实践
周末实验自动化提交数据时,本来没打算写记录的,不过遇到一些问题,觉得可以提提.基本操作就不用写了,搜索过程中都发现了两个博客都出了selenium+python的书,说明操作一搜一大把. 1. 等待页 ...
- win7 64 位 + vs2015 + opencv3.2
下载OpenCv_3.2_vc14 链接:http://pan.baidu.com/s/1eSBu1NG 密码:104g 1.下载好后,进行解压到自己指定的目录: 解压后可以得到: 2.添加环境变量 ...
- 笔记:python (2015)
[开发环境]: Python 3.3 http://rj.baidu.com/soft/detail/25283.html 大小:20.2M 版本:3.3.5150 位数:64 更新日期:2014 ...
- 开源项目初涉(C++自我学习开始)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://i.cnblogs.com/EditPosts.aspx?postid=8428885 临近2018农历新年,我还在上班,哈哈. ...
- Mysql 和 SQLServer 使用SQL差异比较
查询前100条数据 #mysql ; #sqlserver * from table_name ; 从数据库.表 定位表 #mysql写法:库名.表名 select password from Inf ...
- TXLSReadWriteII2 读取数据
TXLSReadWriteII2 按行读取数据(写得复杂了点,实际项目中的,可以自己简化) procedure TformMain.LoadGeneralObject(_type, _col, _ro ...
- 常用的OO设计原则
常用的OO设计原则: 1 封装变化:找出应用中可能需要变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起. 2 针对接口编程,而不是针对实现编程. 3 多用组合,少用继承. 4 松耦合:为了 ...
- python 迭代多个对象
并行迭代 zip for a,b,c in zip(list,list,tuple,list): print a,b,c 串行迭代 itertools.chain a = [1,2,3,4,5] b ...
- 使用setx 命令添加环境变量(Windows)
背景 用GUI的方法可能添加环境变量可能会比较麻烦,为此可采用命令行操作的方式. 步骤 以管理员身份运行 cmd 输入 setx /M "%path%" "%path%[ ...