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