zoukankan      html  css  js  c++  java
  • poj2778 DNA Sequence【AC自动机】【矩阵快速幂】

    DNA Sequence
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 19991   Accepted: 7603

    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

    题意:

    给定m个致病基因序列。问长度为n的DNA序列中有多少个是没有这些序列的。

    思路:

    这道题用到AC自动机的状态转移的性质了。

    当我建好了状态图之后,在某一个状态a时,我可以知道他可以到达的所有状态。Trie树上的一个节点就是一个状态。

    初始矩阵mat[i][j]表示的是从状态i走一步到状态j有几种可能。使用矩阵快速幂,对这个矩阵做n次幂,就可以得到每个两个状态之间走n次总共有多少方案。

    对于一个长为n的串,没有任何一个致病基因序列,那么所有致病基因转移过去的状态都不能算进去。

    我们给每一个致病基因做一个危险标记,同时要注意所有fail可以到达的节点如果是danger的,他自己也要变成danger

    因为这段致病基因作为后缀出现在这个串中了。

      1 #include <iostream>
      2 #include <set>
      3 #include <cmath>
      4 #include <stdio.h>
      5 #include <cstring>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <queue>
      9 #include <map>
     10 //#include <bits/stdc++.h>
     11 using namespace std;
     12 typedef long long LL;
     13 #define inf 0x7f7f7f7f
     14 
     15 int m, n;
     16 const int maxn = 520;
     17 const int maxlen = 2e6 + 5;
     18 
     19 struct Matrix
     20 {
     21     unsigned long long mat[111][111];
     22     int n;
     23     Matrix(){}
     24     Matrix(int _n)
     25     {
     26         n=_n;
     27         for(int i=0;i<n;i++)
     28             for(int j=0;j<n;j++)
     29                 mat[i][j] = 0;
     30     }
     31     Matrix operator *(const Matrix &b)const
     32     {
     33         Matrix ret = Matrix(n);
     34         for(int i=0;i<n;i++)
     35             for(int j=0;j<n;j++)
     36                 for(int k=0;k<n;k++)
     37                     ret.mat[i][j]+=mat[i][k]*b.mat[k][j] % 100000;
     38         return ret;
     39     }
     40     void print()
     41     {
     42         for(int i = 0; i < n; i++){
     43             for(int j = 0; j < n; j++){
     44                 printf("%d ", mat[i][j]);
     45             }
     46             printf("
    ");
     47         }
     48     }
     49 };
     50 
     51 unsigned long long pow_m(unsigned long long a, int n)
     52 {
     53     unsigned long long ret = 1;
     54     unsigned long long tmp = a;
     55     while(n){
     56         if(n & 1)ret *= tmp;
     57         tmp *= tmp;
     58         n >>= 1;
     59     }
     60     return ret;
     61 }
     62 
     63 Matrix pow_M(Matrix a, int n)
     64 {
     65     Matrix ret = Matrix(a.n);
     66     for(int i = 0; i < a.n; i++){
     67         ret.mat[i][i] = 1;
     68     }
     69     Matrix tmp = a;
     70     //cout<<a.n<<endl;
     71     while(n){
     72         if(n & 1)ret = ret * tmp;
     73         tmp = tmp * tmp;
     74         n >>= 1;
     75         //ret.print();
     76         //cout<<endl;
     77     }
     78     return ret;
     79 }
     80 
     81 struct tree{
     82     int fail;
     83     int son[4];
     84     bool danger;
     85 }AC[maxlen];
     86 int tot = 0, id[130];
     87 char s[11];
     88 
     89 void build(char s[])
     90 {
     91     int len = strlen(s);
     92     int now = 0;
     93     for(int i = 0; i < len; i++){
     94         int x = id[s[i]];
     95         if(AC[now].son[x] == 0){
     96             AC[now].son[x] = ++tot;
     97         }
     98         now = AC[now].son[x];
     99     }
    100     AC[now].danger = true;
    101 }
    102 
    103 void get_fail()
    104 {
    105     queue<int>que;
    106     for(int i = 0; i < 4; i++){
    107         if(AC[0].son[i] != 0){
    108             AC[AC[0].son[i]].fail = 0;
    109             que.push(AC[0].son[i]);
    110         }
    111     }
    112     while(!que.empty()){
    113         int u = que.front();
    114         que.pop();
    115         for(int i = 0; i < 4; i++){
    116             if(AC[u].son[i] != 0){
    117                 AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
    118                 que.push(AC[u].son[i]);
    119             }
    120             else{
    121                 AC[u].son[i] = AC[AC[u].fail].son[i];
    122             }
    123             int x = AC[AC[u].son[i]].fail;
    124             if(AC[x].danger){
    125                 AC[AC[u].son[i]].danger = true;
    126             }
    127         }
    128     }
    129 }
    130 
    131 /*int AC_query(char s[])
    132 {
    133     int len = strlen(s);
    134     int now = 0, cnt = 0;
    135     for(int i = 0; i < len; i++){
    136         int x = id[s[i]];
    137         now = AC[now].son[x];
    138         for(int t = now; t; t = AC[t].fail){
    139             if(!AC[t].vis && AC[t].ed != 0){
    140                 cnt++;
    141                 AC[t].vis = true;
    142             }
    143         }
    144     }
    145     return cnt;
    146 }*/
    147 
    148 Matrix getMatrix()
    149 {
    150     Matrix ret = Matrix(tot + 1);
    151     //int now = 0;
    152     for(int i = 0; i < tot + 1; i++){
    153         if(AC[i].danger)continue;
    154         for(int j = 0; j < 4; j++){
    155             if(AC[AC[i].son[j]].danger == false){
    156                 ret.mat[i][AC[i].son[j]]++;
    157             }
    158         }
    159     }
    160     for(int i = 0; i < tot + 1; i++){
    161         ret.mat[i][tot] = 1;
    162     }
    163     return ret;
    164 }
    165 
    166 int main()
    167 {
    168     id['A'] = 0;id['T'] = 1;id['C'] = 2;id['G'] = 3;
    169     //cout<<1<<endl;
    170     while(~scanf("%d%d", &m, &n)){
    171         for(int i = 0; i <= tot; i++){
    172             AC[i].fail = 0;
    173             AC[i].danger = false;
    174             for(int j = 0; j < 4; j++){
    175                 AC[i].son[j] = 0;
    176             }
    177         }
    178         tot = 0;
    179         for(int i = 1; i <= m; i++){
    180             scanf("%s", s);
    181             build(s);
    182         }
    183         AC[0].fail = 0;
    184         get_fail();
    185         Matrix mmm = Matrix(tot + 1);
    186         //int now = 0;
    187         for(int i = 0; i < tot + 1; i++){
    188             if(AC[i].danger)continue;
    189             for(int j = 0; j < 4; j++){
    190                 if(AC[AC[i].son[j]].danger == false){
    191                     mmm.mat[i][AC[i].son[j]]++;
    192                 }
    193             }
    194         }
    195 
    196         mmm = pow_M(mmm, n);
    197         unsigned long long res = 0;
    198         for(int i = 0; i < mmm.n; i++){
    199             res = (res + mmm.mat[0][i]) % 100000;
    200         }
    201 
    202         printf("%lld
    ", res);
    203     }
    204     //getchar();
    205     return 0;
    206 }
  • 相关阅读:
    《Java大学教程》—第12章 案例研究--第2部分
    《Java大学教程》—第11章 案例研究--第1部分
    《Java大学教程》—第10章 图形和事件驱动程序
    《Java大学教程》—第8章 通过继承扩展类
    《Java大学教程》—第7章 类的实现
    《Java大学教程》—第6章 类和对象
    《Java大学教程》—第5章 数组
    《Java大学教程》—第4章 方法的实现
    spring_01概念及案例
    MyEclipse中jsp编码设置
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9899944.html
Copyright © 2011-2022 走看看