• [后缀数组]基因突变


    描述 Description

    最近,jzyz的科学家忽然发现了一种神秘的生物出现在了霞栖湖中,通过提取DNA,科学家发现这个生物的DNA由a.....z共26种碱基对组成,而且这个生物常常容易发生DNA片段的缺失。那么问题来了。科学家想知道DNA片段的缺失对这个生物会产生什么影响。

    给你一段长为N的DNA序列(保证全为小写字母),请求出从x到y-1的片段缺失后,忽略前x-1的长度,他们最长还有多长连续序列是相同的?


    输入格式 Input Format

    第一行为N,表示DNA序列的长度
    接下来一行为DNA序列
    接下来一行为M,表示M次询问。
    接下来的M行为x,y,表示x到y(或y到x)的片段缺失


    输出格式 Output Format
    对于M次询问,输出M行,每行两个数


    样例输入 Sample Input
    10
    aaaaaabaaa
    5
    4 7
    6 5
    6 5
    9 8
    5 10

    样例输出 Sample Output
    0
    1
    1
    2
    1

    /*样例解释

    对于第一个询问

    从第4个碱基到第6个碱基缺失

    故缺失后由
    aaaaaabaaa -> aaabaaa

    因为rRNA是连续读取的,所以两个DNA的相同的片段是aaa
    但是由于我们忽略前三个碱基对,所以相同的长度为0.

    对于第二个询问

    第五个碱基对缺失

    故缺失后由

    aaaaaabaaa -> aaaaabaaa

    相同片段是5,但是忽略前四个,所以相同为1

    */

    注释 Hint
    100% 3<=N<=300000 10<=M,x,y<=30000

    本质上就是求最长公共前缀。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<ctime>
     7 #include<algorithm>
     8 #define MAXN 3001000
     9 #define INF 0x3f3f3f3f
    10 using namespace std;
    11 int N,x,y,rank[MAXN],sa[MAXN],p[MAXN],cnt[MAXN],tmp[MAXN],height[MAXN],t[MAXN*4+500];
    12 char s[MAXN];
    13 inline int read()
    14 {
    15     int x=0,f=1;  char ch=getchar();
    16     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
    17     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
    18     return x*f;
    19 }
    20 bool equ(int x,int y,int l) {return rank[x]==rank[y]&&rank[x+l]==rank[y+l];}
    21 void doubling()
    22 {
    23     for(int i=1;i<=N;i++)  rank[i]=s[i],sa[i]=i;
    24     for(int pos=0,sig=255,l=0,i;pos<N;sig=pos)
    25     {
    26         for(i=N-l+1,pos=0;i<=N;i++)  p[++pos]=i;
    27         for(i=1;i<=N;i++)  if(sa[i]>l)  p[++pos]=sa[i]-l;
    28         for(i=1;i<=sig;i++)  cnt[i]=0;
    29         for(i=1;i<=N;i++)  cnt[rank[i]]++;
    30         for(i=1;i<=sig;i++)  cnt[i]+=cnt[i-1];
    31         for(i=N;i;i--)  sa[cnt[rank[p[i]]]--]=p[i];
    32         for(pos=0,i=1;i<=N;i++)  
    33             tmp[sa[i]]=equ(sa[i],sa[i-1],l)?pos:++pos;
    34         for(int i=1;i<=N;i++)  rank[i]=tmp[i];
    35         l=!l?1:l<<1;
    36     }
    37 }
    38 void get_height()
    39 {
    40     for(int i=1,j=0,k;i<=N;i++)
    41     {
    42         if(!(k=sa[rank[i]-1]))  {j=0;  continue;}
    43         if(j)  j--;
    44         while(s[i+j]==s[k+j])  j++;
    45         height[rank[i]]=j;
    46     }
    47 }
    48 void build(int p,int l,int r)
    49 {
    50     if(l==r)  {t[p]=height[l];  return;}
    51     int mid=(l+r)/2;
    52     build(p*2,l,mid);
    53     build(p*2+1,mid+1,r);
    54     t[p]=min(t[p*2],t[p*2+1]);
    55 }
    56 int getnum(int p,int l,int r)
    57 {
    58     if(x>r||y<l)  return INF;
    59     if(x<=l&&y>=r)  return t[p];
    60     int mid=(l+r)/2;
    61     int lx=getnum(p*2,l,mid),ly=getnum(p*2+1,mid+1,r);
    62     return min(lx,ly);
    63 }
    64 void ask()
    65 {
    66     int m=read();
    67     for(int i=1;i<=m;i++)
    68     {
    69         int tx=read(),ty=read();
    70         if(tx==ty)  {printf("%d
    ",N-tx+1);  continue;}
    71         if(rank[tx]<rank[ty]) x=rank[tx]+1,y=rank[ty];
    72         else x=rank[ty]+1,y=rank[tx];
    73         printf("%d
    ",getnum(1,1,N));
    74     }
    75 }
    76 int main()
    77 {
    78     //freopen("cin.in","r",stdin);
    79     //freopen("cout.out","w",stdout);
    80     N=read();
    81     for(int i=1;i<=N;i++)  scanf("%c",&s[i]);
    82     doubling();
    83     get_height();
    84     build(1,1,N);
    85     ask();
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    Struts2的配置中:Could not find action or result 问题的解决方法
    Oracle 数据库 Record is locked by another user 问题解决办法
    设计模式六大原则(2):里氏替换原则
    在PL/SQL中 自动复制转换StringBuffer的SQL
    反射setAccessible()方法
    对允许任意图片上传的发布内容模式的啊哈的想法
    如果你真的想做一件事,你一定会找到一个方法;如果你不想做一件事,你一定会找到一个借口.
    xaml 的 intellisense失效的解决办法
    Blog技术词汇之Rss篇 什么是Rss以及其定义[翻译]
    多个存储过程之间相互调用的原子性问题
  • 原文地址:https://www.cnblogs.com/chty/p/5843758.html
Copyright © 2020-2023  润新知