poj2778 DNA Sequence AC自动机+矩阵乘法

来源:互联网 发布:ubuntu tensorflow安装 编辑:程序博客网 时间:2024/06/06 20:04

DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 15900 Accepted: 6137
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
Source

POJ Monthly–2006.03.26,dodo

题意:给你一些串,让你求有多少个长度为m的串不包含这些串。
一开始我想的容斥。。把不合法方案剪掉,但是发现不合法方案数非常难计算,因为子串出现的位置不固定,根本没地方下手。。然后就dp喽,但是这么大,用矩阵乘法优化了一下,结果半天RE,不知道哪里错了,看了看题解和我一样啊,一看代码发现怎么人家的getfail好像不太一样?一脸懵逼。结果发现都差不多啊,怎么会有问题呢。。
最后发现我手抖把加进队列的达成了fail节点。。mdzz。。

顺便熟悉一下结构体,毕竟以后肯定很有用。。

#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1005;typedef long long ll;const int mo=1e5;int a[N][10],val[N],fail[N],q[N],ans;int tot=0,n;char s[N];ll m;struct Matrix{    ll ret[105][105];    Matrix(){memset(ret,0,sizeof(ret));}    void ini()    {        fo(i,0,tot)ret[i][i]=1;    }}g;Matrix operator *(Matrix a,Matrix b){    Matrix c;    fo(k,0,tot)    fo(i,0,tot)if (a.ret[i][k])    fo(j,0,tot)if (b.ret[k][j])        c.ret[i][j]=(c.ret[i][j]+a.ret[i][k]*b.ret[k][j]%mo)%mo;    return c;}Matrix operator ^(Matrix a,int b){    Matrix ans;ans.ini();    for(;b;b>>=1,a=a*a)        if (b&1)ans=ans*a;    return ans;}inline void ins(){    int x=0,len=strlen(s);    fo(i,0,len-1)    {        int c;        if (s[i]=='A')c=1;        else if (s[i]=='T')c=2;        else if (s[i]=='C')c=3;        else if (s[i]=='G')c=4;        c--;        if(!a[x][c])a[x][c]=++tot;        x=a[x][c];    }    val[x]=1;}inline void getfail(){    int t=0,w=0;    fo(i,0,3)if (a[0][i])q[w++]=a[0][i];    while(t<w)    {        int x=q[t++];        fo(i,0,3)        if (a[x][i])        {            int k=fail[x];            while (k&&!a[k][i])k=fail[k];            k=a[k][i];            fail[a[x][i]]=k;            if (val[k])val[a[x][i]]=1;            q[w++]=a[x][i];        }        else a[x][i]=a[fail[x]][i];    }}inline void build(){    fo(i,0,tot)if (!val[i])        fo(k,0,3)if (!val[a[i][k]])        g.ret[i][a[i][k]]++;}int main(){    scanf("%d%lld",&n,&m);    fo(i,1,n)    {        scanf("%s",s);        ins();    }    getfail();    build();    g=g^m;    ll ans=0;    fo(i,0,tot)ans=(ans+g.ret[0][i])%mo;    printf("%lld",ans);}
0 0
原创粉丝点击