zoukankan      html  css  js  c++  java
  • [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))

    代码在此

  • 相关阅读:
    C语言温习杂记
    C语言变量类型与内存管理
    解析搜狗新闻语料库
    关于clang, scan-build, 和clang test
    Clang checker类总结
    让你的checker出现在clang的checker list中
    Clang安装配置解释
    Operators 操作
    cumulative_distribution累积分布
    SVM
  • 原文地址:https://www.cnblogs.com/reverymoon/p/8955438.html
Copyright © 2011-2022 走看看