POJ 2778 AC自动机+矩阵相乘

来源:互联网 发布:php抓取微信文章 编辑:程序博客网 时间:2024/05/22 05:27
点击打开链接
DNA Sequence
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 10873 Accepted: 4150

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 3ATACAGAA

Sample Output

36

Source

POJ Monthly--2006.03.26,dodo
解体报告:点击打开链接
经典的题目,经典的矩阵相乘。看了两天,才模模糊胡有点头绪。
//1068K235MS#include<stdio.h>#include<string.h>#define M 100005#define mod 100000char str[M];int head,tail,idx;//队列的头和尾struct node{    node *next[4];    node *fail;//失效指针    int kind,isword;} *que[M],s[M];int id(char ch){    if(ch=='A')return 0;    else if(ch=='T')return 1;    else if(ch=='C')return 2;    return 3;}node *NewTrie(){    node *tmp=&s[idx];    for(int i=0; i<4; i++)tmp->next[i]=NULL;    tmp->isword=0;    tmp->fail=NULL;    tmp->kind=idx++;    return tmp;}void insert(node *root){    node *p=root;    int i=0,index;    while(str[i])    {        if(p->next[id(str[i])]==NULL)p->next[id(str[i])]=NewTrie();        p=p->next[id(str[i])];        i++;    }    p->isword=1;}void build_ac(node *root){    root->fail=NULL;    que[tail++]=root;    while(head<tail)    {        node *temp=que[head++];        for(int i=0; i<4; i++)        {            if(temp->next[i]==NULL)            {                if(temp==root)temp->next[i]=root;                else temp->next[i]=temp->fail->next[i];            }            else            {                if(temp==root)temp->next[i]->fail=root;                else                {                    temp->next[i]->fail=temp->fail->next[i];                    if(temp->next[i]->fail->isword)                        temp->next[i]->isword=1;                }                que[tail++]=temp->next[i];            }        }    }}struct Matrix{    long long m[107][107];} mat;Matrix mult(Matrix m1,Matrix m2){    Matrix ans;    memset(ans.m,0,sizeof(ans.m));    for(int i=0; i<idx; i++)        for(int k=0; k<idx; k++)        {            if(m1.m[i][k]==0)continue;            for(int j=0; j<idx; j++)            {                ans.m[i][j]+=(long long)m1.m[i][k]*m2.m[k][j];                if(ans.m[i][j]>=mod)ans.m[i][j]%=mod;            }        }    return ans;}Matrix pow_mod(Matrix m1,int n){    Matrix ans;    for(int i=0; i<idx; i++)        for(int j=0; j<idx; j++)            ans.m[i][j]=i==j;    while(n)    {        if(n&1)ans=mult(ans,m1);        m1=mult(m1,m1);        n>>=1;    }    return ans;}int main(){    int n,m;    while(scanf("%d%d",&m,&n)!=EOF)    {        head=tail=idx=0;        node *root=NewTrie();        while(m--)        {            scanf("%s",str);            insert(root);        }        build_ac(root);        memset(mat.m,0,sizeof(mat.m));        for(int i=0; i<idx; i++)            for(int j=0; j<4; j++)            {                node *son=s[i].next[j];                if(!son->isword&&!s[i].isword)                    mat.m[i][son->kind]++;            }        mat=pow_mod(mat,n);        long long ans=0;        for(int i=0; i<idx; i++)        {            ans+=mat.m[0][i];            if(ans>=mod)ans-=mod;        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击