[TJOI2017]DNA --- 后缀数组

[TJOI2017]DNA

题目描述

加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,

有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状。

现在研究人员想知道这个基因在DNA链\(S_{0}\)上的位置。

所以你需要统计在一个表现出吃藕性状的人的DNA序列\(S_{0}\)上,有多少个子串可能是该基因,

即有多少个\(S_{0}\)的子串修改小于等于三个字母能够变成S。

输入输出格式

输入格式:

第一行有一个数T,表示有几组数据

每组数据第一行一个长度不超过\(10^{5}\)的碱基序列\(S_{0}\)

每组数据第二行一个长度不超过\(10^{5}\)的吃藕基因序列S

输出格式:

共T行,第i行表示第i组数据中,在\(S_{0}\)中有多少个与S等长的连续子串可能是表现吃藕性状的碱基序列

输入输出样例

输入样例#1:

1

ATCGCCCTA

CTTCA

输出样例#1:

2

说明

对于20%的数据,\(S_{0}\),S的长度不超过\(10^{4}\)

对于20%的数据,\(S_{0}\),S的长度不超过\(10^{5}\),0<T<=10

作为后缀数组的模板集成题来做的。

首先考虑一个比较容易想到的事情.

\(S_{0}\)大串中存在长度和\(S\)相同的串只有\(n\)个

因此只要一个一个暴力判断就好了。

怎么判断快一点??

比如串‘ACGAC‘和串‘ACAAC‘

前面的‘AC‘相同,因此可以直接调用。

到了‘G‘和‘A‘不同,来一个\(tim\)计数器表示失配了几次,此时,\(tim++\)

接下了后面的‘AC‘相同,因此这个子串和模式串只有一处不同。

可以发现,每当\(tim<=3\)匹配完成一次时,\(ans++\)

那么,怎么得到‘AC‘相同这个过程??

用后缀数组的LCP或者哈希二分LCP或后缀树跑LCP即可

后缀数组复杂度\(O(n \log n + n * 6)\) = \(O(n \log n)\)

代码在此

原文地址:https://www.cnblogs.com/reverymoon/p/8955438.html

时间: 2024-08-01 12:32:36

[TJOI2017]DNA --- 后缀数组的相关文章

[BZOJ4892][TJOI2017]DNA(后缀数组)

题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状.现在研究人员想知道这个基因在DNA链S0上的位置.所以你需要统计在一个表现出吃藕性状的人的DNA序列S0上,有多少个连续子串可能是该基因,即有多少个S0的连续子串修改小于等于三个字母能够变成S. 输入输出格式 输入格式: 第一行有一个数T,表示有几组数据 每组数据第一行一个长度不超过10^5的碱基

[TJOI2017]DNA——后缀数组求LCP

题目大意: 给定一个文本串和一个模式串,求文本串中有多少个连续的子串和模式串相差不超过三个字符. 思路: 算是一道后缀数组的模板题. 直接做lcp,然后遇到匹配不上的就跳,跳的次数不能超过三次. 具体地,将两个字符串连在一起,中间加一个分隔符,然后求出height,用rmq维护height数组的区间最小值即可. /*======================================= * Author : ylsoi * Time : 2019.2.5 * Problem : luog

你可以在 Python 中轻易创建一个后缀数组

我想告诉你一个关于后缀数组的故事.在一段时间里,我正在西雅图的一家公司面试,当时好奇的是如何最有效地创建一个用于可执行二进制文件的diff.我的研究给我带来了后缀数组和后缀树.后缀数组只是,将字符串的所有后缀排序,储存到有序列表中.后缀树是类似的,但是比列表更像BSTree.这些算法相当简单,一旦你进行了排序操作,它们就具有很快的性能.他们解决的问题是,找到两个字符串之间最长的公共子串(或者在这种情况下是字节列表). 你可以在 Python 中轻易创建一个后缀数组: >>> magic

后缀数组(多个字符串的最长公共子串)—— POJ 3294

对应POJ 题目:点击打开链接 Life Forms Time Limit:6666MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description Problem C: Life Forms You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial tra

POJ3294:Life Forms(后缀数组)

Description You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height, colour, wrinkles, ears, eyebrows and the like. A few bear no human resemblance; these typically have geometric or

Blue Jeans - poj 3080(后缀数组)

大致题意: 给出n个长度为60的DNA基因(A腺嘌呤 G鸟嘌呤 T胸腺嘧啶 C胞嘧啶)序列,求出他们的最长公共子序列 使用后缀数组解决 1 #include<stdio.h> 2 #include<string.h> 3 char str[6200],res[6200]; 4 int num[6200],loc[6200]; 5 int sa[6200],rank[6200],height[6200]; 6 int wa[6200],wb[6200],wv[6200],wd[620

wenbao与后缀数组

倍增算法(da) 1 #define maxn 1000001 2 int wa[maxn],wb[maxn],wv[maxn],wss[maxn]; 3 4 int cmp(int *r, int a, int b, int l) { 5 return r[a] == r[b] && r[a+l] == r[b+l]; 6 } 7 8 void da(int *r, int *sa, int n, int m) { 9 int i, j, p, *x = wa, *y = wb, *t;

SPOJ 705 Distinct Substrings(后缀数组)

[题目链接] http://www.spoj.com/problems/SUBST1/ [题目大意] 给出一个串,求出不相同的子串的个数. [题解] 对原串做一遍后缀数组,按照后缀的名次进行遍历, 每个后缀对答案的贡献为n-sa[i]+1-h[i], 因为排名相邻的后缀一定是公共前缀最长的, 那么就可以有效地通过LCP去除重复计算的子串. [代码] #include <cstdio> #include <cstring> #include <algorithm> usi

hdu5769--Substring(后缀数组)

题意:求含有某个字母的某个字符串的不同子串的个数 题解:后缀数组,记录每个位置距离需要出现的字母的距离就可以了.因为不太了解后缀模版卡了一会,还是很简单的. 记住sa和height数组都是1-n的下标. //后缀数组 #include <stdio.h> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll;