zoukankan      html  css  js  c++  java
  • 日常小测:生物进阶

    题意:给定样本串模式串(只出现4个字母A,C,G,T),求模式串出现多少次。这里匹配定义如下:不一定要严格匹配,在附近k个单位有这个字符都算匹配,可以多个模式串的字符匹配上同一个样本串里的字符。

    策爷讲过的大原题啊跪。。。。基本思路是分开考虑每个字母。对于以一个位置i开头,我们考虑这里是否能匹配上,需要处理出这里能匹配的字母个数,如果4个字母分别的匹配个数加起来刚好等于模式串长度,则可以匹配。怎么快速求呢?答案是FFT!

    分开考虑每个字母。对于正在考虑的我们标为1,其他为0.模式串也这样表示,然后把它放到位置上去&。还不够,如果我们把模式串倒着,并且用前导零去补位,会发现对于每个位置,可以用一个叉积的式子来表示它的匹配数。。果断FFT啊

    时间复杂度O(Sigma*(n+m)log) 其中Sigma是字母种类,对于这道题是4。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N ((1<<20)+5)
     4 #define eps 0.5
     5 const double PI=acos(-1);
     6 int len,n,m,k,match[N],rev[N],ans;
     7 char st1[N],st2[N],ch[4]={'A','C','G','T'};
     8 struct vec{
     9     double r,i;
    10     vec operator + (const vec& w){return (vec){r+w.r,i+w.i};}
    11     vec operator - (const vec& w){return (vec){r-w.r,i-w.i};}
    12     vec operator * (const vec& w){return (vec){r*w.r-i*w.i,w.i*r+i*w.r};}
    13 }A[N],B[N];
    14 inline void FFT(vec* x,int f){
    15     for(int i=1;i<=len;i++) if(i<rev[i]) swap(x[i],x[rev[i]]);
    16     for(int lnow=2;lnow<=len;lnow<<=1){
    17         vec w0=(vec){cos(2*PI/lnow*f),sin(2*PI/lnow*f)},t1,t2,w;
    18         for(int i=0;i<len;i+=lnow){
    19             w=(vec){1,0};
    20             for(int j=0;j<lnow/2;j++,w=w*w0){
    21                 t1=x[i+j]; t2=w*x[i+j+lnow/2];
    22                 x[i+j]=t1+t2; x[i+j+lnow/2]=t1-t2;
    23             }
    24         }
    25     } 
    26 }
    27 inline int read(){
    28     int x=0,f=1; char a=getchar();
    29     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
    30     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
    31     return x*f;
    32 }
    33 int main(){
    34     n=read(); m=read(); k=read();
    35     scanf("%s%s",st1,st2); int t=0; 
    36     for(len=1;len<=2*n;len<<=1,t++); t--;
    37     for(int i=1;i<=len;i++) rev[i]=(rev[i>>1]>>1)|(i&1?1<<t:0);
    38     for(int last,i=0;i<4;i++){
    39         for(int j=0;j<=len;j++) A[j]=B[j]=(vec){0,0}; 
    40         last=0;
    41         for(int j=0;j<n;j++) 
    42             if(st1[j]==ch[i]){
    43                 for(int t=max(j-k,last);t<=j+k && t<n;t++) A[t].r=1.0;
    44                 last=j+k;
    45             }
    46         for(int j=0;j<m;j++)
    47         if(st2[j]==ch[i]) B[len/2-j+1].r=1.0;
    48         FFT(A,1); FFT(B,1);
    49         for(int j=0;j<=len;j++) A[j]=A[j]*B[j];
    50         FFT(A,-1);
    51         for(int j=0;j<n;j++)
    52         match[j]+=(int)(A[j+len/2].r/len+eps);
    53     }
    54     for(int i=0;i<n;i++){
    55         if(match[i]==m) ans++;
    56     }
    57     printf("%d
    ",ans);
    58     return 0;
    59 }
  • 相关阅读:
    大规模特征构建实践总结
    大数据分析在新型智慧能源建设中的应用
    非局部神经网络,打造未来神经网络基本组件
    异常处理机制
    myecplise debug时怎么看源码 和怎么导入项目中框架的源码
    mybatis 学习的总结
    oracle学习总结2(pl/sql 游标 异常的处理 存储过程和函数 包 触发器)
    Oracle学习的总结
    Oracle 11 g 2R安装以及sql Development
    SpringMVC源代码学习(六)HanderMapping详解
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6215977.html
Copyright © 2011-2022 走看看