• poj 2278 DNASequnce AC自动机


    地址:http://poj.org/problem?id=2778

    题目:

    DNA Sequence
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 15453   Accepted: 5964

    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自动机,然后所有节点可看做状态转移图。呃,懒得画图了,你们可以百度下。然后根据转移图建立矩阵,之后快速幂即可。
      之前一直忘了把end【x】为1的节点的所有子节点的end标记为1,wa的不省人事。

      1 #include <queue>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 
      6 const long long mod=1e5;
      7 struct MM
      8 {
      9     int r,c;
     10     long long mx[105][105];
     11     MM(int rr=0,int cc=0){r=rr,c=cc;}
     12     friend MM operator *(MM ta,MM tb)
     13     {
     14         MM tc(ta.r,tb.c);
     15         for(int i=0;i<tc.r;i++)
     16             for(int j=0;j<tc.c;j++)
     17             {
     18                 tc.mx[i][j]=0;
     19                 for(int k=0;k<tb.r;k++)
     20                     tc.mx[i][j]=(tc.mx[i][j]+ta.mx[i][k]*tb.mx[k][j])%mod;
     21             }
     22         return tc;
     23     }
     24     friend MM operator ^(MM ta,int num)
     25     {
     26         MM ret(ta.r,ta.c);                          //r==c
     27         memset(ret.mx,0,sizeof ret.mx);
     28         for(int i=0;i<ta.r;i++) ret.mx[i][i]=1;    //µ¥Î»¾ØÕó
     29         while(num)
     30         {
     31             if(num&1)
     32                 ret=ta*ret;
     33             num>>=1;
     34             ta=ta*ta;
     35         }
     36         return ret;
     37     }
     38 }mm;
     39 struct AC_auto
     40 {
     41     const static int LetterSize = 4;
     42     const static int TrieSize = 4*1010;
     43 
     44     int tot,root,fail[TrieSize],end[TrieSize],next[TrieSize][LetterSize];
     45 
     46     int newnode(void)
     47     {
     48         memset(next[tot],-1,sizeof(next[tot]));
     49         end[tot] = 0;
     50         return tot++;
     51     }
     52 
     53     void init(void)
     54     {
     55         tot = 0;
     56         root = newnode();
     57     }
     58 
     59     int getidx(char x)
     60     {
     61         if(x=='A')return 0;
     62         else if(x=='C')return 1;
     63         else if(x=='G')return 2;
     64         else return 3;
     65     }
     66 
     67     void insert(char *ss)
     68     {
     69         int len = strlen(ss);
     70         int now = root;
     71         for(int i = 0; i < len; i++)
     72         {
     73             int idx = getidx(ss[i]);
     74             if(next[now][idx] == -1)
     75                 next[now][idx] = newnode();
     76             now = next[now][idx];
     77         }
     78         end[now]=1;
     79     }
     80 
     81     void build(void)
     82     {
     83         queue<int>Q;
     84         fail[root] = root;
     85         for(int i = 0; i < LetterSize; i++)
     86             if(next[root][i] == -1)
     87                 next[root][i] = root;
     88             else
     89                 fail[next[root][i]] = root,Q.push(next[root][i]);
     90         while(Q.size())
     91         {
     92             int now = Q.front();Q.pop();
     93             if(end[fail[now]])end[now]=1;
     94             for(int i = 0; i < LetterSize; i++)
     95             if(next[now][i] == -1)   next[now][i] = next[fail[now]][i];
     96             else
     97                 fail[next[now][i]] = next[fail[now]][i],Q.push(next[now][i]);
     98         }
     99     }
    100 
    101     int buildmm(int n)
    102     {
    103         int cnt = 0;
    104         mm.c=mm.r=tot;
    105         for(int i = 0; i < tot; i++)
    106         for(int j = 0; j < 4; j++)
    107         if(!end[next[i][j]])
    108             mm.mx[i][next[i][j]]++;
    109         mm=mm ^ n;
    110         for(int i = 0; i < tot; i++)
    111             cnt = (cnt + mm.mx[0][i]) % mod;
    112         return cnt;
    113     }
    114 };
    115 
    116 
    117 AC_auto ac;
    118 char sa[20];
    119 int main(void)
    120 {
    121     int n,m;
    122     scanf("%d%d",&n,&m);
    123     ac.init();
    124     for(int i=1;i<=n;i++)
    125         scanf("%s",sa),ac.insert(sa);
    126     ac.build();
    127     printf("%d
    ",ac.buildmm(m));
    128     return 0;
    129 }
  • 相关阅读:
    远程桌面无法复制粘贴
    软件无法启动,不提示具体错误
    从数据库统计出某张表中某个字段重复次数
    程序员何去何从
    SQL Server中TRUNCATE 和 DELETE的区别
    关于C#自定义控件注释说明
    C#的winform程序下如何实现文本编辑框(TextBox)的Hint提示文字效果
    ubuntu固定内网ip地址
    数据库的优化处理 Memory cached
    MYSQL管理之主从同步管理
  • 原文地址:https://www.cnblogs.com/weeping/p/5950351.html
Copyright © 2020-2023  润新知