zoukankan      html  css  js  c++  java
  • poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 11860   Accepted: 4527

    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

      几个月没编AC自动机,突然编一下感觉之痛苦。

      主要问题一点是fail指针构造时没有即使break掉,另一点是tail标记上传时需要加入一个while循环。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 100
    #define MAXT 100
    #define MOD 100000
    typedef long long qword;
    
    struct trie_node
    {
            int ptr[4];
            int fail;
            char w;
            bool tl;
    }trie[MAXT];
    int topt=1;
    char str[MAXN];
    void Add_word(char *str)
    {
            int now=1;
            int ind;
            while (*str)
            {
                    ind=*(str++)-'A';
                    if (!trie[now].ptr[ind])
                    {
                            trie[now].ptr[ind]=++topt;
                            trie[topt].w=ind+'A';
                            trie[topt].tl=false;
                    }
                    now=trie[now].ptr[ind];
            }
            trie[now].tl=true;
    }
    int q[MAXN];
    void Build_Ac()
    {
            int head=-1,tail=0;
            int now,temp;
            int i,j;
            q[0]=1;
            trie[1].fail=1;
            while (head<tail)
            {
                    now=q[++head];
                    for (i=0;i<4;i++)
                    {
                            if (!trie[now].ptr[i])continue;
                            q[++tail]=trie[now].ptr[i];
                            if (now==1)
                            {
                                    trie[trie[now].ptr[i]].fail=now;
                                    continue;
                            }
                            temp=trie[now].fail;
                            while(temp!=1)
                            {
                                    if (trie[temp].ptr[i])
                                    {
                                            trie[trie[now].ptr[i]].fail=trie[temp].ptr[i];
                                            break;
                                    }
                                    temp=trie[temp].fail;
                            }
                            if (!trie[trie[now].ptr[i]].fail)
                                    trie[trie[now].ptr[i]].fail=trie[1].ptr[i];
                            if (!trie[trie[now].ptr[i]].fail)
                                    trie[trie[now].ptr[i]].fail=1;
                    }
            }
            for (i=1;i<=topt;i++)
            {
                    for (j=0;j<4;j++)
                    {
                            if (!trie[i].ptr[j])
                            {
                                    temp=trie[i].fail;
                                    while (temp!=1)
                                    {
                                            if (trie[temp].ptr[j])
                                            {
                                                    trie[i].ptr[j]=trie[temp].ptr[j];
                                                    break;
                                            }
                                            temp=trie[temp].fail;
                                    }
                                    if (!trie[i].ptr[j])
                                            trie[i].ptr[j]=trie[1].ptr[j];
                                    if (!trie[i].ptr[j])
                                            trie[i].ptr[j]=1;
                            }
                    }
            }
            j=3;
            while (j--)
            {
                    for (i=0;i<=tail;i++)
                    {
                            if (trie[trie[i].fail].tl)
                                    trie[i].tl=true;
                    }
            }
    }
    struct matrix
    {
            int n,m;
            qword a[MAXN][MAXN];
            matrix()
            {
                    memset(a,0,sizeof(a));
            }
            void pm()
            {
                    int i,j;
                    for (i=1;i<=n;i++)
                    {
                            for (j=1;j<=m;j++)
                            {
                                    printf("% 4d ",a[i][j]);
                            }
                            printf("
    ");
                    }
                    printf("
    ");
            }
    }m1,r1,m2;
    matrix operator *(matrix &m1,matrix &m2)
    {
            if (m1.m!=m2.n)throw 1;
            matrix ret;
            ret.n=m1.n;
            ret.m=m2.m;
            int i,j,k;
            for (i=1;i<=ret.n;i++)
            {
                    for (j=1;j<=ret.m;j++)
                    {
                            for (k=1;k<=m1.m;k++)
                            {
                                    ret.a[i][j]=(ret.a[i][j]+m1.a[i][k]*m2.a[k][j])%MOD;
                            }
                    }
            }
            return ret;
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            //        freopen("output.txt","w",stdout);
            int n,m,i,j,k,x,y,z;
            scanf("%d%d
    ",&m,&n);
            topt=1;
            trie[1].w='#';
            for (i=0;i<m;i++)
            {
                    scanf("%s",str);
                    x=strlen(str);
                    for (j=0;j<x;j++)
                    {
                            switch(str[j])
                            {
                                    case 'A':str[j]='A';break;
                                    case 'G':str[j]='B';break;
                                    case 'C':str[j]='C';break;
                                    case 'T':str[j]='D';break;
                            }
                    }
                    Add_word(str);
            }
            Build_Ac();
            m1.m=m1.n=topt;
            for (i=1;i<=topt;i++)
            {
                    for (j=0;j<4;j++)
                    {
                            if (trie[trie[i].ptr[j]].tl)continue;
                            m1.a[trie[i].ptr[j]][i]++;
                    }
            }
            //        m1.pm();
            m2.m=1,m2.n=topt;
            m2.a[1][1]=1;
            while (n)
            {
                    if (n&1)
                    {
                            m2=m1*m2;
                    }
                    m1=m1*m1;
                    n>>=1;
            }
            /*
            for (i=1;i<=n;i++)
            {
                    m2=m1*m2;
                    //        m2.pm();
            }*/
            qword ans=0;
            for (i=1;i<=topt;i++)
            {
                    ans+=m2.a[i][1];
                    ans%=MOD;
            }
            printf("%d
    ",ans);
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    你能用多长时间停车?
    中国威胁论好像还挺严重的
    热爱生命
    lunix下shell脚本批量获取文件,批量修改文件内容
    sql数据操作的若干心得(二)向表中自动插入自增的ID
    Asp.net开发之旅动态产生控件
    Asp.net开发之旅GridView中嵌入DropDownList的一点心得
    Asp.net开发之旅开发环境
    Asp.net开发之旅简单的引用母版页
    Sql数据操作的若干心得
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4045072.html
Copyright © 2011-2022 走看看