[BZOJ4892][TJOI2017]DNA(后缀数组)
题目描述
加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状。现在研究人员想知道这个基因在DNA链S0上的位置。所以你需要统计在一个表现出吃藕性状的人的DNA序列S0上,有多少个连续子串可能是该基因,即有多少个S0的连续子串修改小于等于三个字母能够变成S。
输入输出格式
输入格式:
第一行有一个数T,表示有几组数据 每组数据第一行一个长度不超过10^5的碱基序列S0
每组数据第二行一个长度不超过10^5的吃藕基因序列S
输出格式:
共T行,第i行表示第i组数据中,在S0中有多少个与S等长的连续子串可能是表现吃藕性状的碱基序列
输入输出样例
说明
对于20%的数据,S0,S的长度不超过10^4
对于20%的数据,S0,S的长度不超过10^5,0<T<=10
两个串连起来中间插个特殊字符然后后缀数组求四次LCP即可。
启示:永远不要低估SA模板的默写难度。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const int N=;
int n,m,T,ans,x[N],y[N],sa[N],log[N],c[N],rk[N],h[N],st[N][];
char s[N],s1[N],S[N]; int Cmp(int a,int b,int l){ return y[a]==y[b] && y[a+l]==y[b+l]; } void build(int m){
memset(y,,sizeof(y));
rep(i,,m) c[i]=;
rep(i,,n) c[x[i]]++;
rep(i,,m) c[i]+=c[i-];
for (int i=n; i; i--) sa[c[x[i]]--]=i;
for (int k=,p=; p<n; k<<=,m=p){
p=;
rep(i,n-k+,n) y[++p]=i;
rep(i,,n) if (sa[i]>k) y[++p]=sa[i]-k;
rep(i,,m) c[i]=;
rep(i,,n) c[x[y[i]]]++;
rep(i,,m) c[i]+=c[i-];
for (int i=n; i; i--) sa[c[x[y[i]]]--]=y[i];
rep(i,,n) y[i]=x[i]; p=; x[sa[]]=;
rep(i,,n) x[sa[i]]=Cmp(sa[i-],sa[i],k) ? p : ++p;
}
} void get(){
int k=;
rep(i,,n) rk[sa[i]]=i;
rep(i,,n){
for (int j=sa[rk[i]-]; i+k<=n && j+k<=n && S[i+k]==S[j+k]; k++);
h[rk[i]]=k; if (k) k--;
}
} void rmq(){
rep(i,,n) st[i][]=h[i];
rep(i,,log[n])
rep(j,,n-(<<i)+) st[j][i]=min(st[j][i-],st[j+(<<(i-))][i-]);
} int ask(int l,int r){
if (l>r) swap(l,r);
l++; int t=log[r-l+];
return min(st[l][t],st[r-(<<t)+][t]);
} int main(){
log[]=; rep(i,,N-) log[i]=log[i>>]+;
for (scanf("%d",&T); T--; ){
scanf("%s",s+); scanf("%s",s1+);
int n0=strlen(s+),n1=strlen(s1+);
rep(i,,n0) S[i]=s[i]; S[strlen(s+)+]='$';
rep(i,,n1) S[strlen(s+)+i+]=s1[i];
n=n0+n1+;
rep(i,,n) x[i]=(int)S[i];
build(); get(); rmq(); ans=;
rep(i,,n0-n1+){
int a=i,b=n0+,f=;
rep(j,,){
int t=ask(rk[a],rk[b]);
if (b+t>n) { f=; break; }
if (i+t>n0) break;
a+=t+; b+=t+;
}
if (f) ans++;
}
printf("%d\n",ans);
}
return ;
}
[BZOJ4892][TJOI2017]DNA(后缀数组)的更多相关文章
- [TJOI2017]DNA --- 后缀数组
[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S, 有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个 ...
- [TJOI2017] DNA - 后缀数组,稀疏表
[TJOI2017] DNA Description 求模式串与主串的匹配次数,容错不超过三个字符. Solution 枚举每个开始位置,进行暴力匹配,直到失配次数用光或者匹配成功.考虑到容错量很小, ...
- 洛谷P3763 [TJOI2017]DNA(后缀数组 RMQ)
题意 题目链接 Sol 这题打死我也不会想到后缀数组的,应该会全程想AC自动机之类的吧 但知道这题能用后缀数组做之后应该就不是那么难了 首先把\(S\)和\(S0\)拼到一起跑,求出Height数组 ...
- bzoj4892 [TJOI2017]DNA
bzoj4892 [TJOI2017]DNA 给定一个匹配串和一个模式串,求模式串有多少个连续子串能够修改不超过 \(3\) 个字符变成匹配串 \(len\leq10^5\) hash 枚举子串左端点 ...
- BZOJ.4892.[TJOI2017]DNA(后缀自动机/后缀数组)
题目链接 \(Description\) 给出两个串\(S,T\),求\(T\)在\(S\)中出现了多少次.出现是指.可以有\(3\)次(\(3\)个字符)不匹配(修改使其匹配). \(Solutio ...
- BZOJ4892:[TJOI2017]dna(hash)
Description 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表 ...
- BZOJ4892 Tjoi2017dna(后缀数组)
对每个子串暴力匹配至失配三次即可.可以用SA查lcp.然而在bzoj上被卡常了.当然也可以二分+哈希或者SAM甚至FFT. #include<iostream> #include<c ...
- 【BZOJ4892】DNA(后缀数组)
[BZOJ4892]DNA(后缀数组) 题面 BZOJ 洛谷 题解 看到这道题目,我第一反应是\(FFT\)??? 然后大力码出了一个\(FFT\) 就像这样 #include<iostream ...
- 洛谷P3763 [Tjoi2017]DNA 【后缀数组】
题目链接 洛谷P3763 题解 后缀数组裸题 在BZOJ被卡常到哭QAQ #include<algorithm> #include<iostream> #include< ...
随机推荐
- 设置display:inline-block产生间隙
display:inline-block产生间隙,是由于换行在内的空白符 display:inline-block在IE下仅仅是触发了layout,而它本是行布局,触发后,块元素依然还是行布局.所以需 ...
- java检验银行卡号
/* 校验过程: 1.从卡号最后一位数字开始,逆向将奇数位(1.3.5等等)相加. 2.从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,将个位十位数字相加,即将其减去9),再求和 ...
- USB基础介绍
(转)USB (Universal Serial Bus) 全文地址:http://vlewang.blog.163.com/blog/static/105878151201032804347546/ ...
- MGR Switch single-Primary to Muti_primary
MGR single_primary 切换 Muti-Primary 模式 root@localhost [(none)]>select * from performance_schema.re ...
- python 协程嵌套
import asyncio import time now = lambda: time.time() async def do_some_work(x): print('Waiting: ', x ...
- html的loadrunner脚本2
Action(){ char buf[1911]; //¶¨Òå×Ö·ûÊý×飬Ö÷ÒªÓÃÓÚдÈëXML±¨Îĵ½»º³åÇø char str_Body[4086]; //³Ð½Ó±¨Î ...
- Vue.js写一个SPA登录页面的过程
技术栈 vue.js 主框架 vuex 状态管理 vue-router 路由管理 一般过程 在一般的登录过程中,一种前端方案是: 检查状态:进入页面时或者路由变化时检查是否有登录状态(保存在cooki ...
- awk中NF,NR的含义
awk中NF和NR的意义,其实你已经知道NF和NR的意义了,NF代表的是一个文本文件中一行(一条记录)中的字段个数,NR代表的是这个文本文件的行数(记录数).在编程时特别是在数据处理时经常用到.建议你 ...
- JS模块化规范AMD之RequireJS
1.基本操作 加载 JavaScript 文件(入口文件) RequireJS以一个相对于baseUrl的地址来加载所有的代码 <script data-main="scripts/m ...
- 【58沈剑架构系列】主从DB与cache一致性
本文主要讨论这么几个问题: (1)数据库主从延时为何会导致缓存数据不一致 (2)优化思路与方案 一.需求缘起 上一篇<缓存架构设计细节二三事>中有一个小优化点,在只有主库时,通过“串行化” ...