ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[TJOI2017]DNA

2019-03-10 11:38:40  阅读:228  来源: 互联网

标签:include DNA int S0 TJOI2017 序列 return cp


Description:

加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状。现在研究人员想知道这个基因在DNA链S0上的位置。所以你需要统计在一个表现出吃藕性状的人的DNA序列S0上,有多少个连续子串可能是该基因,即有多少个S0的连续子串修改小于等于三个字母能够变成S。

Hint:

考虑分别算每个字母的匹配,再累加起来
故枚举四个字母,把原串的为该字母的位赋为1,其他赋为0,匹配串相反
这样就能不重不漏的统计出不匹配的数量
统计后直接输出<=3的位置

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1 
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=4e5+5,inf=1e9;
const double PI=acos(-1);
int n,m,k,lim=1,ans,l,r[mxn],cnt[mxn];
char s[mxn],t[mxn];

inline int read() {
    char c=getchar(); int x=0,f=1;
    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
    return x*f;
}
inline int chkmax(int &x,int y) {if(x<y) x=y;}
inline int chkmin(int &x,int y) {if(x>y) x=y;}

struct cp {
    double x,y;
    cp (double xx=0,double yy=0) {x=xx,y=yy;}
    friend cp operator + (cp a,cp b) {
        return cp(a.x+b.x,a.y+b.y);
    }
    friend cp operator - (cp a,cp b) {
        return cp(a.x-b.x,a.y-b.y);
    }
    friend cp operator * (cp a,cp b) {
        return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    }
}a[mxn],b[mxn];

void FFT(cp *p,int opt) 
{
    for(int i=0;i<lim;++i)
        if(i<r[i]) swap(p[i],p[r[i]]);
    for(int mid=1;mid<lim;mid<<=1) {
        cp wn=cp(cos(PI/mid),opt*sin(PI/mid));
        for(int len=mid<<1,j=0;j<lim;j+=len) {
            cp w(1,0);
            for(int k=0;k<mid;++k,w=w*wn) {
                cp x=p[j+k],y=w*p[j+mid+k];
                p[j+k]=x+y,p[j+mid+k]=x-y;
            }
        }
    }   
}

void solve(char c) {
    memset(a,0,sizeof(a)); memset(b,0,sizeof(b));
    for(int i=0,las=-inf;i<n;++i) {
        if(s[i]!=c) a[i]=1; 
    }
    for(int i=0;i<m;++i) b[i].x=t[m-i-1]==c;
    lim=1,l=0;
    while(lim<=n+m-2) lim<<=1,++l;
    for(int i=0;i<lim;++i)
        r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    FFT(a,1); FFT(b,1); 
    for(int i=0;i<=lim;++i) a[i]=a[i]*b[i];
    FFT(a,-1);
    for(int i=0;i<lim;++i) cnt[i]+=(int )(a[i].x/lim+0.5);


}

int main()
{
    int T;
    cin>>T;
    while(T--) {
    memset(cnt,0,sizeof(cnt)); ans=0;
    scanf("%s %s",s,t); n=strlen(s),m=strlen(t);
    for(int i=0;i<4;++i) solve("ACTG"[i]);
    for(int i=m-1;i<n;++i) ans+=cnt[i]<=3;
    printf("%d\n",ans);
    }
    return 0;
}

标签:include,DNA,int,S0,TJOI2017,序列,return,cp
来源: https://www.cnblogs.com/list1/p/10504712.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有