【POJ2778】 DNA Sequence AC自动机+矩阵快速幂

来源:互联网 发布:mac终端bash 编辑:程序博客网 时间:2024/06/13 07:50

DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 14224 Accepted: 5486

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

题意:给你n个病毒,求m长度的正常DNA序列的个数;
思路:在trie树上的递推,二维数组表示路径的方案数,快速幂解;
从0的dp[0][i]的和;

#include<iostream>#include<algorithm>#include<stdio.h>#include<queue>#include<string.h>using namespace std;long long  b[110][110];int n,m;char s[115];int MOD=100000;int  ans=0;int flag[110];int tot;int nex[110];long long   cc[110][110];long long  ccc[110][110];struct node{        int ch[4];}t[110];int val(char s){    if(s=='A') return 0;    if(s=='C') return 1;    if(s=='T') return 2;    if(s=='G') return 3;}inline void insert(char s[]){//  cout<<"     "<<s[0]<<endl;//  cout<<tot<<endl;    int now=0;        for(int i=0;s[i];i++)        {        int ii=val(s[i]);//cout<<i<<endl;                if(!t[now].ch[ii])                {                        t[now].ch[ii]=++tot;                }                now=t[now].ch[ii];        }  flag[now]=1;}queue<int> q;inline void AC(){        for(int i=0;i<4;i++) if(t[0].ch[i]) q.push(t[0].ch[i]);        while(!q.empty())        {                int now=q.front();                q.pop();                int next=nex[now];                for(int i=0;i<4;i++)                {        //  if(now==3) cout<<t[3].ch[2]<<endl;        //  if(now==4)   cout<<"     "<<t[now].ch[i]<<endl;                        if(t[now].ch[i])                        {                                   nex[t[now].ch[i]]=t[next].ch[i];                                flag[t[now].ch[i]]|=flag[t[next].ch[i]];                q.push(t[now].ch[i]);                        }                        else t[now].ch[i]=t[next].ch[i];                }        }}inline void ma_cheng(long long a[110][110],long long  tmp[110][110]){        for(int i=0;i<=tot;i++)        for(int j=0;j<=tot;j++)    {        cc[i][j]=0;        for(int k=0;k<=tot;k++)            {                    cc[i][j]+=a[i][k]*tmp[k][j];                    cc[i][j]%=MOD;            }    }//  for(int i=0;i<=5;i++)    //{    //for(int j=0;j<=5;j++)    //cout<<cc[i][j]<<"   ";    //cout<<endl;    //}//cout<<endl;        for(int i=0;i<=tot;i++)        for(int j=0;j<=tot;j++)    {        tmp[i][j]=cc[i][j];    }}inline void ma_mi(int x){    for(int i=0;i<=tot;i++)    for(int j=0;j<=tot;j++)    ccc[i][j]=b[i][j];        while(x>0)        {//  cout<<"   "<<x<<endl;                if(x&1) ma_cheng(ccc,b);                ma_cheng(ccc,ccc);                x>>=1;        }}int main(){        scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        {                scanf("%s",s);                insert(s);        }        AC();    //cout<<tot<<endl;        for(int i=0;i<=tot;i++)        if(!flag[i])        {                for(int j=0;j<4;j++)                if(!flag[t[i].ch[j]])                {                        b[i][t[i].ch[j]]++;                }        }//  cout<<tot<<endl;    //for(int i=0;i<=7;i++)//{    //for(int j=0;j<=7;j++)    //cout<<b[i][j]<<"   ";//cout<<endl;//}        ma_mi(m-1);    ans=0;        for(int i=0;i<=tot;i++)        if(!flag[i])        {                ans+=b[0][i];        ans%=MOD;        }        cout<<ans<<endl;}
1 0