ZOJ 3430 Detect the Virus(AC自动机)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430

题意:给你n个编码后的模式串,和m个编码后的主串,求原来主串中含有模式串的个数

思路:首先要将模式串解码成未编码前来建立ac自动机,然后解码主串扫描统计即可。

code:

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <queue>

  4 #include <set>

  5 using namespace std;

  6 const int KIND = 256;

  7 const int MAXN = 32800;

  8 

  9 struct Trie

 10 {

 11     int next[MAXN][KIND], fail[MAXN], id[MAXN];

 12     int root, L, num;

 13     int create()

 14     {

 15         for (int i = 0; i < KIND; ++i)

 16             next[L][i] = -1;

 17         return L++;

 18     }

 19     void init()

 20     {

 21         L = 0;

 22         num = 0;

 23         memset(id, 0, sizeof(id));

 24         root = create();

 25     }

 26     void insert(unsigned char str[], int len)

 27     {

 28         int now = root;

 29         for (int i = 0; i < len; ++i)

 30         {

 31             if (-1 == next[now][str[i]])

 32                 next[now][str[i]] = create();

 33             now = next[now][str[i]];

 34         }

 35         id[now] = ++num;

 36     }

 37     void build()

 38     {

 39         queue<int>Q;

 40         fail[root] = root;

 41         for (int i = 0; i < KIND; ++i)

 42         {

 43             if (-1 == next[root][i])

 44                 next[root][i] = root;

 45             else

 46             {

 47                 fail[next[root][i]] = root;

 48                 Q.push(next[root][i]);

 49             }

 50         }

 51         while (!Q.empty())

 52         {

 53             int now = Q.front();

 54             Q.pop();

 55             for (int i = 0; i < KIND; ++i)

 56             {

 57                 if (-1 == next[now][i])

 58                     next[now][i] = next[fail[now]][i];

 59                 else

 60                 {

 61                     fail[next[now][i]] = next[fail[now]][i];

 62                     Q.push(next[now][i]);

 63                 }

 64             }

 65         }

 66     }

 67     int query(unsigned char str[], int len)

 68     {

 69         set<int>S;

 70         int now = root;

 71         for (int i = 0; i < len; ++i)

 72         {

 73             now = next[now][str[i]];

 74             int temp = now;

 75             while (temp != root)

 76             {

 77                 if (id[temp]) S.insert(id[temp]);

 78                 temp = fail[temp];

 79             }

 80         }

 81         return (int)S.size();

 82     }

 83 };

 84 

 85 Trie ac;

 86 char buf[4000];

 87 unsigned char temp[4000];

 88 unsigned char str[2500];

 89 

 90 unsigned char Tran(char ch)

 91 {

 92     if (ch >= 'A' && ch <= 'Z') return ch - 'A';

 93     if (ch >= 'a' && ch <= 'z') return ch - 'a' + 26;

 94     if (ch >= '0' && ch <= '9') return ch - '0' + 52;

 95     if (ch == '+') return 62;

 96     return 63;

 97 }

 98 

 99 int Decode(int len)

100 {

101     int k = 0;

102     for (int i = 0; i < len; i += 4)

103     {

104         str[k++] = (temp[i]<<2)|(temp[i + 1]>>4);

105         if (i + 2 < len) str[k++] = (temp[i + 1]<<4)|(temp[i + 2]>>2);

106         if (i + 3 < len) str[k++] = (temp[i + 2]<<6)|(temp[i + 3]);

107     }

108     return k;

109 }

110 

111 int main()

112 {

113     int n, m;

114     while (scanf("%d", &n) != EOF)

115     {

116         ac.init();

117         for (int i = 0; i <n; ++i)

118         {

119             scanf("%s", buf);

120             int len = strlen(buf);

121             while ('=' == buf[len - 1]) --len;

122             for (int j = 0; j < len; ++j) temp[j] = Tran(buf[j]);

123             ac.insert(str, Decode(len));

124         }

125         ac.build();

126         scanf("%d", &m);

127         for (int i = 0; i < m; ++i)

128         {

129             scanf("%s", buf);

130             int len = strlen(buf);

131             while ('=' == buf[len - 1]) --len;

132             for (int j = 0; j < len; ++j) temp[j] = Tran(buf[j]);

133             printf("%d\n", ac.query(str, Decode(len)));

134         }

135         printf("\n");

136     }

137     return 0;

138 }

 

你可能感兴趣的:(AC自动机)