zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Protocol Buffer使用
    uImage、zImage、bzImage、vlinzx区别
    nginx学习之一
    Android屏幕底部弹出DialogFragment(3)
    C++11 | 正则表达式(4)
    Android绘图之渐隐动画
    Android动态Java代码调整window大小
    Spring Boot交流平台
    Java日志实战及解析
    Android WindowManager悬浮窗:不需要申请权限实现悬浮
  • 原文地址:https://www.cnblogs.com/tellmewtf/p/2909332.html
Copyright © 2011-2022 走看看