zoukankan      html  css  js  c++  java
  • POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)

    DNA Sequence

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 17160   Accepted: 6616

    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

     
      1 //2017-08-10
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <queue>
      6 #define ll long long
      7 
      8 using namespace std;
      9 
     10 const int K = 4;
     11 const int N = 500010;
     12 const int M = 12;
     13 const int MOD = 100000;
     14 
     15 struct Matrix{  
     16     ll a[M*M][M*M];  
     17     int r, c; 
     18 }mat, tmp;  
     19 
     20 Matrix multi(Matrix x, Matrix y)//矩阵乘法
     21 {
     22     Matrix z;
     23     memset(z.a, 0, sizeof(z.a));  
     24     z.r = x.r, z.c = y.c;
     25     for(int i = 0; i < x.r; i++){
     26         for(int k = 0; k < x.c; k++)//加速优化
     27         {
     28             if(x.a[i][k] == 0) continue;
     29             for(int j = 0; j< y.c; j++)
     30                 z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j]) % MOD) % MOD;
     31         }
     32     }
     33     return z;
     34 }
     35 
     36 void Matrix_pow(int n)//矩阵快速幂
     37 {  
     38     Matrix tmp;
     39     tmp.c = mat.c;
     40     tmp.r = mat.r;
     41     memset(tmp.a, 0, sizeof(tmp.a));
     42     for(int i = 0; i < tmp.c; i++)
     43         tmp.a[i][i] = 1;
     44     while(n){  
     45         if(n & 1)  
     46             tmp = multi(tmp, mat);  
     47         mat = multi(mat, mat);  
     48         n >>= 1;  
     49     }  
     50     int ans = 0;
     51     for(int i = 0; i < tmp.c; i++)
     52         ans = (ans + tmp.a[0][i]) % MOD;
     53     printf("%d
    ", ans);
     54 }  
     55 
     56 struct AC_automation
     57 {
     58     //node nodes[N], *root, *superRoot, *cur;
     59     int nex[M*M][4], fail[M*M], match[M*M];
     60     int root, CNT;
     61     int newNode(){
     62         for(int i = 0; i < K; i++)
     63             nex[CNT][i] = -1;
     64         match[CNT++] = 0;
     65         return CNT-1;
     66     }
     67     int Hash(char ch)
     68     {
     69         if(ch == 'A')return 0;
     70         else if(ch == 'C')return 1;
     71         else if(ch == 'T')return 2;
     72         else if(ch == 'G')return 3;
     73     }
     74     void init(){
     75         CNT = 0;
     76         root = newNode();
     77     }
     78     void Insert(char s[]){//向字典树中插入一个字符串
     79         int n = strlen(s);
     80         int cur = root;
     81         for(int i = 0; i < n; i++){
     82             int p = Hash(s[i]);
     83             if(nex[cur][p] == -1)
     84                   nex[cur][p] = newNode();
     85             cur = nex[cur][p];
     86         }
     87         match[cur]++;
     88     }
     89     void build(){//构建自动机
     90         queue<int> que;
     91         fail[root] = root;
     92         for(int i = 0; i < K; i++){
     93             if(nex[root][i] == -1)
     94                 nex[root][i] = root;
     95             else{
     96                 fail[nex[root][i]] = root;
     97                 que.push(nex[root][i]);
     98             }
     99         }
    100         while(!que.empty()){
    101             int cur = que.front();
    102             if(match[fail[cur]])match[cur] = 1;
    103             que.pop();
    104             for(int i = 0; i < K; i++){
    105                 if(nex[cur][i] == -1){
    106                     nex[cur][i] = nex[fail[cur]][i];
    107                 }else{
    108                     fail[nex[cur][i]] = nex[fail[cur]][i];
    109                     que.push(nex[cur][i]);
    110                 }
    111             }
    112         }
    113     }
    114     void to_marix(){
    115         memset(mat.a, 0, sizeof(mat.a));
    116         mat.r = mat.c = CNT;
    117         for(int i = 0; i < CNT; i++){
    118             for(int j = 0; j < 4; j++)
    119                   if(!match[nex[i][j]])
    120                     mat.a[i][nex[i][j]]++;
    121         }
    122         // for(int i = 0; i < CNT; i++){
    123         //     for(int j = 0; j < CNT; j++)
    124         //           cout<<mat.a[i][j]<<" ";
    125         //     cout<<endl;
    126         // }
    127     }
    128 };
    129 
    130 char str[M];
    131 AC_automation ac;
    132 
    133 int main()
    134 {
    135     int n, m;
    136     while(scanf("%d%d", &m, &n)!=EOF)
    137     {
    138         ac.init();
    139         for(int i = 0; i < m; i++){
    140             scanf("%s", str);
    141             ac.Insert(str);
    142         }
    143         ac.build();
    144         ac.to_marix();
    145         Matrix_pow(n);
    146     }
    147 
    148     return 0;
    149 }
  • 相关阅读:
    线段树 建树 单点修改 单点/区间查询
    JAVAEE学期总结
    Spring框架教程IDEA版-----更新中
    第一章操作系统引论-------批处理、分时、实时各个操作系统特点 进程与线程的区别
    读《阿法狗围棋系统的简要分析》
    matlab启动后的默认路径
    从长辈们的故事谈起
    在成为一名老司机的路上不要狂奔
    物理学与其它科学的关系
    读《现象级带货网红的自我修养》
  • 原文地址:https://www.cnblogs.com/Penn000/p/7341649.html
Copyright © 2011-2022 走看看