首页 > 代码库 > 【POJ】2278 DNA Sequence

【POJ】2278 DNA Sequence

各种wa后,各种TLE。注意若AC非法,则ACT等一定非法。而且尽量少MOD。

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 #include <queue>  5 using namespace std;  6   7 #define MAXN 105  8 #define NXTN 4  9  10 char str[15]; 11  12 typedef struct Matrix { 13     int n; 14     __int64 map[MAXN][MAXN]; 15     Matrix() {} 16     Matrix(int nn) { 17         n = nn; 18         for (int i=0; i<nn; ++i) 19             for (int j=0; j<nn; ++j) 20                 map[i][j] = 0; 21     } 22 } Matrix; 23  24 int getval(char ch) { 25     switch (ch) { 26     case A: return 0; 27     case C: return 1; 28     case T: return 2; 29     case G: return 3; 30     default: return 0; 31     } 32 } 33  34 struct AC { 35     int next[MAXN][NXTN], fail[MAXN], v[MAXN]; 36     int n, root; 37     void init() { 38         n = 0; 39         root = newNode(); 40     } 41     int newNode() { 42         fail[n] = 0; 43         v[n] = 0; 44         memset(next[n], -1, sizeof(next[n])); 45         return n++; 46     } 47     void create(char s[]) { 48         int i = 0, id; 49         int cur = root; 50  51         while (s[i]) { 52             id = getval(s[i]); 53             ++i; 54             if (next[cur][id] == -1) 55                 next[cur][id] = newNode(); 56             cur = next[cur][id]; 57         } 58         v[cur] = 1; 59     } 60     void build() { 61         int i, cur; 62         queue<int> Q; 63  64         fail[root] = root; 65         for (i=0; i<NXTN; ++i) { 66             if (next[root][i] == -1) 67                 next[root][i] = root; 68             else { 69                 fail[next[root][i]] = root; 70                 Q.push(next[root][i]); 71             } 72         } 73  74         while (!Q.empty()) { 75             cur = Q.front(); 76             Q.pop(); 77             if (v[fail[cur]])    // important 78                 v[cur] = 1; 79             for (i=0; i<NXTN; ++i) { 80                 if (next[cur][i] == -1) 81                     next[cur][i] = next[fail[cur]][i]; 82                 else { 83                     fail[next[cur][i]] = next[fail[cur]][i]; 84                     Q.push(next[cur][i]); 85                 } 86             } 87         } 88     } 89     Matrix query() { 90         int i, j; 91  92         Matrix mat(n); 93  94         for (i=0; i<n; ++i) { 95             for (j=0; j<NXTN; ++j) { 96                 if (v[next[i][j]] == 0) 97                     ++mat.map[i][next[i][j]]; 98             } 99         }100         return mat;101     }102 };103 104 AC ac;105 106 Matrix mmul(Matrix a, Matrix b) {107     int i, j, k, n = a.n;108     Matrix ret(n);109 110     for (i=0; i<n; ++i)111         for (j=0; j<n; ++j)112             for (k=0; k<n; ++k) {113                 ret.map[i][j] += a.map[i][k]*b.map[k][j];114                 ret.map[i][j] %= 100000;115             }116     return ret;117 }118 119 void mpow(Matrix a, int n) {120     Matrix ret(a.n);121     int i;122     __int64 ans;123 124     for (i=0; i<ret.n; ++i)125         ret.map[i][i] = 1;126 127     while (n) {128         if (n & 1)129             ret = mmul(ret, a);130         a = mmul(a, a);131         n >>= 1;132     }133 134     ans = 0;135     for (i=0; i<ret.n; ++i) {136         //printf("i:%I64d\n", ret.map[0][i]);137         ans += ret.map[0][i];138         ans %= 100000;139     }140     printf("%I64d\n", ans);141 }142 143 int main() {144     int m, n;145     int i;146 147     while (scanf("%d %d", &m, &n) != EOF) {148         ac.init();149         for (i=0; i<m; ++i) {150             scanf("%s", str);151             ac.create(str);152         }153         ac.build();154         Matrix mat = ac.query();155         //printf("mat.n=%d\n", mat.n);156         mpow(mat, n);157     }158 159     return 0;160 }