1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 typedef long long LL;
  5 #define MAXN 110
  6 #define MOD 100000
  7 using namespace std;
  8 char str[MAXN];
  9 int size;
 10 struct Matrix {
 11     LL mat[MAXN][MAXN];
 12     void Zero() {
 13         memset(mat, 0, sizeof(mat));
 14     }
 15     void Unit() {
 16         int i;
 17         for (i = 0; i <= size; i++)
 18             mat[i][i] = 1;
 19     }
 20 };
 21 struct Trie {
 22     int fail, next[4];
 23     bool end;
 24     void Init() {
 25         fail = 0;
 26         end = false;
 27         memset(next, 0, sizeof(next));
 28     }
 29 };
 30 Matrix a, b;
 31 Trie tree[MAXN];
 32 Matrix operator *(const Matrix &a, const Matrix &b) {
 33     Matrix temp;
 34     int i, j, k;
 35     temp.Zero();
 36     for (i = 0; i <= size; i++) {
 37         for (j = 0; j <= size; j++) {
 38             for (k = 0; k <= size; k++)
 39                 temp.mat[i][j] += a.mat[i][k] * b.mat[k][j];
 40             temp.mat[i][j] %= MOD;
 41         }
 42     }
 43     return temp;
 44 }
 45 inline int GET(char ch) {
 46     if (ch == 'A')
 47         return 0;
 48     if (ch == 'C')
 49         return 1;
 50     if (ch == 'G')
 51         return 2;
 52     return 3;
 53 }
 54 void Insert(char *s) {
 55     int now, t;
 56     for (now = 0; *s; s++) {
 57         t = GET(*s);
 58         if (!tree[now].next[t]) {
 59             tree[++size].Init();
 60             tree[now].next[t] = size;
 61         }
 62         now = tree[now].next[t];
 63     }
 64     tree[now].end = true;
 65 }
 66 void BFS() {
 67     int now, i, p;
 68     queue<int> q;
 69     q.push(0);
 70     while (!q.empty()) {
 71         now = q.front();
 72         q.pop();
 73         for (i = 0; i < 4; i++) {
 74             if (tree[now].next[i]) {
 75                 p = tree[now].next[i];
 76                 if (now)
 77                     tree[p].fail = tree[tree[now].fail].next[i];
 78                 tree[p].end |= tree[tree[p].fail].end;
 79                 q.push(p);
 80             } else
 81                 tree[now].next[i] = tree[tree[now].fail].next[i];
 82         }
 83     }
 84 }
 85 void DoIt(int m) {
 86     int i, j, p;
 87     a.Zero();
 88     for (i = 0; i <= size; i++) {
 89         for (j = 0; j < 4; j++) {
 90             if (!tree[i].end) {
 91                 p = tree[i].next[j];
 92                 if (p) {
 93                     if (!tree[p].end)
 94                         a.mat[i][p]++;
 95                 } else
 96                     a.mat[i][0]++;
 97             }
 98         }
 99     }
100     b.Zero();
101     b.Unit();
102     for (; m; m >>= 1) {
103         if (m & 1)
104             b = b * a;
105         a = a * a;
106     }
107 }
108 int main() {
109     LL ans;
110     int n, m, i;
111     while (~scanf("%d%d", &n, &m)) {
112         tree[0].Init();
113         for (size = i = 0; i < n; i++) {
114             scanf(" %s", str);
115             Insert(str);
116         }
117         BFS();
118         DoIt(m);
119         for (ans = i = 0; i <= size; i++)
120             ans += b.mat[0][i];
121         printf("%lld\n", ans % MOD);
122     }
123     return 0;
124 }
posted on 2012-08-04 00:48  DrunBee  阅读(493)  评论(0编辑  收藏  举报