poj2778DNA Sequence(AC自动机)

DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 15327 Accepted: 5914

Description

It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence contains segment ATC then it may mean that the animal may have a genetic disease. Until now scientists have found several those segments, the problem is how many kinds of DNA sequences of a species don't contain those segments. 

Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n. 

Input

First line contains two integer m (0 <= m <= 10), n (1 <= n <=2000000000). Here, m is the number of genetic disease segment, and n is the length of sequences. 

Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10. 

Output

An integer, the number of DNA sequences, mod 100000.

Sample Input

4 3
AT
AC
AG
AA

Sample Output

36
题意:

有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列。(仅含A,T,C,G四个字符)

思路:

这边的博客解释的十分清楚了。http://blog.csdn.net/luyuncheng/article/details/8643001

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1100000;
int d[maxn],ans[maxn];
struct Trie{
    int next[maxn][26],fail[maxn],end[maxn];
    int root,L;
    int newnode(){
        for(int i=0;i<26;i++)
            next[L][i]=-1;
        end[L++]=0;
        return L-1;
    }
    void init(){
        L=0;
        root=newnode();
    }
    void insert(char buf[]){
        int len=strlen(buf);
        int now=root;
        for(int i=0;i<len;i++){
            if(next[now][buf[i]-'a']==-1)
                next[now][buf[i]-'a']=newnode();
            now=next[now][buf[i]-'a'];
        }
        end[now]=1;
        d[now]=len;
    }
    void build(){
        queue<int>     q;
        fail[root]=root;
        for(int i=0;i<26;i++)
            if(next[root][i]==-1)
                next[root][i]=root;
            else{
                fail[next[root][i]]=root;
                q.push(next[root][i]);
            }
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=0;i<26;i++)
                if(next[now][i]==-1)
                    next[now][i]=next[fail[now]][i];
                else{
                    fail[next[now][i]]=next[fail[now]][i];
                    q.push(next[now][i]);
                }
        }
    }
    void slove(char buf[]){
        int len=strlen(buf);
        int now=root;
        int index;
        for(int i=0;i<len;i++){
            if(buf[i]>='a'&&buf[i]<='z')
                index=buf[i]-'a';
            else if(buf[i]>='A' && buf[i]<='Z')
                index=buf[i]-'A';
            else continue;
            now=next[now][index];
            int temp=now;
            while(temp!=root){
                if(end[temp]){
                    ans[i+1]-=1;
                    ans[i-d[temp]+1]+=1;
                    break;    
                }
                temp=fail[temp];
            }
        }
    }
};
char buf[maxn];
Trie ac;
int main(){
    int T,i,n,len;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        ac.init();
        for(int i=0;i<n;i++){
            scanf("%s",buf);
            ac.insert(buf);
        }
        getchar();
        ac.build();
        gets(buf);
        memset(ans,0,sizeof(ans));
        ac.slove(buf);
        long long res=0;
        len=strlen(buf);
        for(int i=0;i<len;i++){
            res+=ans[i];
            if(res<=0)
                printf("%c",buf[i]);
            else printf("*");
        }
        puts("");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值