AC自动机

百度文库搜trie图

利用安全图的概念可以做POJ2778

POJ2778
 1 #include <cstdio>
 2 #include <cstring>
 3 const int p = 1e5;
 4 int trie[170][4], map[255], fail[150], q[2000000], cnt;
 5 bool v[170];
 6 struct M {
 7     long long s[170][170];
 8     M () { memset (s, 0, sizeof s); }
 9 }x, ans;
10 inline M operator * (const M & a, const M & b)
11 {
12     M c;
13     for (int i = 0; i <= cnt; i ++)
14         for (int j = 0; j <= cnt; j ++)
15             for (int k = 0; k <= cnt; k ++)
16                 c.s[i][j] += a.s[i][k] * b.s[k][j], c.s[i][j] %= p;
17     return c;
18 }
19 inline void add (char * s)
20 {
21     int p = 0;
22     for (; * s; s ++)
23     {
24         if (trie[p][map[*s]] == 0)
25             trie[p][map[*s]] = ++ cnt;
26         p = trie[p][map[*s]];
27     }
28     v[p] = true;
29 }
30 inline void build ()
31 {
32     int h = 1, t = 2;
33     while (h < t)
34     {
35         int u = q[h ++];
36         for (int i = 0; i < 4; i ++)
37             if (trie[u][i])
38             {
39                 if (u)
40                     fail[trie[u][i]] = trie[fail[u]][i], v[trie[u][i]] |= v[trie[fail[u]][i]];
41                     //v[trie[u][i]] |= v[trie[fail[u]][i]] spread the dangerous !!!
42                 q[t ++] = trie[u][i];
43             }
44             else
45                 trie[u][i] = trie[fail[u]][i];
46     }
47 }
48 int main ()
49 {int m, n;
50     map['A'] = 0;map['T'] = 1;map['C'] = 2;map['G'] = 3;
51     scanf ("%d%d", &m, &n);char s[20];
52     for (int i = 1; i <= m; i ++)
53         scanf ("%s", s), add (s);
54     build ();
55     ans.s[0][0] = 1;
56     for (int i = 0; i <= cnt; i ++)
57     {
58         if (v[i]) continue;
59         for (int j = 0; j < 4; j ++)
60             if (!v[trie[i][j]])
61                 x.s[i][trie[i][j]] ++;
62     }
63     for (; n; n >>= 1)
64     {
65         if (n & 1)
66             ans = ans * x;
67         x = x * x;
68     }int z (0);
69     for (int i = 0; i <= cnt; i ++)
70         z += ans.s[0][i], z %= p;
71     printf ("%d", z);
72     return 0;
73     return 0;
74 }

每个节点都有一个确定的前驱fail

将fail边反向fail边构成一棵树 可以做ali

ali
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <vector>
  4 #include <iostream>
  5 using namespace std;
  6 const int N = 501000;
  7 int L, v[N], ans[N], b[N], a[N], st[N], ed[N], key[N], next[N], head[N], cnt, a_c, trie[N][26], q[N], graphmr, fa[N], fail[N];char s[N];
  8 typedef pair <int, int> pi;
  9 vector <pi> vec[N];
 10 vector <pi>:: iterator it;
 11 inline void add (int x, int y)
 12 {
 13     key[graphmr] = y;
 14     next[graphmr] = head[x];
 15     head[x] = graphmr ++;
 16 }
 17 inline void DFS (int x)
 18 {
 19     a[++ a_c] = x;st[x] = a_c;
 20     for (int i = head[x]; ~ i; i = next[i])
 21         DFS (key[i]);
 22     a[++ a_c] = x;ed[x] = a_c;
 23 }
 24 inline void build (char * s)
 25 {
 26     memset (head, -1, sizeof head);
 27     int p = 0, line = 0;
 28     for (int i = 0; i <= L; i ++)
 29     {
 30         if (s[i] >= 'a' && s[i] <= 'z')
 31             trie[p][s[i] - 'a'] = ++ cnt, fa[cnt] = p, p = cnt;
 32         if (s[i] == 'P')
 33         {
 34             ++ line;
 35             v[line] = p;
 36         }
 37         if (s[i] == 'B')
 38             p = fa[p];
 39     }
 40     int h = 1, t = 2;
 41     while (h < t)
 42     {
 43         int u = q[h ++];
 44         for (int i = 0; i < 26; i ++)
 45             if (trie[u][i])
 46             {
 47                 if (u)
 48                     fail[trie[u][i]] = trie[fail[u]][i], add (trie[fail[u]][i], trie[u][i]);
 49                 else
 50                     add (u, trie[u][i]);
 51                 q[t ++] = trie[u][i];
 52             }
 53             else
 54                 trie[u][i] = trie[fail[u]][i];
 55     }
 56     DFS (0);
 57 }
 58 inline void updata (int x, int r)
 59 {
 60     for (; x <= 2 * L; x += x & -x)
 61         b[x] += r;
 62 }
 63 inline int query (int x)
 64 {
 65     int z (0);
 66     for (; x; x -= x & -x)
 67         z += b[x];
 68     return z;
 69 }
 70 inline void sol (char * s)
 71 {
 72     int line = 0, p = 0;
 73     for (int i = 0; i < L; i ++)
 74     {
 75         if (s[i] >= 'a' && s[i] <= 'z')
 76             p = trie[p][s[i] - 'a'], updata (st[p], 1);
 77         if (s[i] == 'P')
 78         {
 79             ++ line;
 80             for (it = vec[line].begin (); it != vec[line].end (); it ++)
 81                 ans[it->second] = query (ed[v[it->first]]) - query (st[v[it->first]] - 1);
 82         }
 83         if (s[i] == 'B')
 84             updata (st[p], -1), p = fa[p];
 85     }
 86 }
 87 int main ()
 88 {
 89     scanf ("%s", s);L = strlen (s);
 90     build (s);int n;
 91     scanf ("%d", &n);
 92     for (int i = 1, x, y; i <= n; i ++)
 93         scanf ("%d%d", &x, &y), vec[y].push_back (pi (x, i));
 94     //for (int i = 1; i <= a_c; i ++)
 95     //    printf ("%d ", a[i]);puts ("");
 96     sol (s);
 97     for (int i = 1; i <= n; i ++)
 98         printf ("%d\n", ans[i]);
 99     return 0;
100 }

 

posted @ 2013-02-08 16:58  Moretimes  阅读(185)  评论(0编辑  收藏  举报