• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
mhy12345
博客园    首页    新随笔    联系   管理    订阅  订阅

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("\n");
                }
                printf("\n");
        }
}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\n",&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\n",ans);
        return 0;
}

 

by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

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

posted @ 2014-10-23 09:57  mhy12345  阅读(140)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3