Problem Description
3 2 AB DCB DACB 3 ABC CDE GHI ABCCDEFIHG 4 ABB ACDEE BBB FEEE A[2B]CD[4E]F
0 3 2HintIn the second case in the sample input, the reverse of the program is ‘GHIFEDCCBA’, and ‘GHI’ is a substring of the reverse, so the program is infected by virus ‘GHI’.
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int const MAX = 5100005;
char s[1005], get[MAX], text[MAX];
struct node
{
node *next[26];
node *fail;
bool end;
node()
{
memset(next, NULL, sizeof(next));
fail = NULL;
end = false;
}
};
void Insert(node *p, char *s)
{
for(int i = 0; s[i] != '\0'; i++)
{
int idx = s[i] - 'A';
if(p -> next[idx] == NULL)
p -> next[idx] = new node();
p = p -> next[idx];
}
p -> end = true;
}
void AC_Automation(node *root)
{
queue <node*> q;
q.push(root);
while(!q.empty())
{
node *p = q.front();
q.pop();
for(int i = 0; i < 26; i++)
{
if(p -> next[i])
{
if(p == root)
p -> next[i] -> fail = root;
else
p -> next[i] -> fail = p -> fail -> next[i];
q.push(p -> next[i]);
}
else
{
if(p == root)
p -> next[i] = root;
else
p -> next[i] = p -> fail -> next[i];
}
}
}
}
int Query(node *root, char *s)
{
int ans = 0;
node *p = root;
for(int i = 0; s[i] != '\0'; i++)
{
int idx = s[i] - 'A';
while(!p -> next[idx] && p != root)
p = p -> fail;
p = p -> next[idx];
if(!p)
{
p = root;
continue;
}
node *tmp = p;
while(tmp != root)
{
if(tmp -> end)
{
ans ++;
tmp -> end = false;
}
else
break;
tmp = tmp -> fail;
}
}
return ans;
}
void reverse(char *s)
{
char tmp;
int len = strlen(s) - 1;
for(int i = 0; i < len / 2 + 1; i++)
swap(s[i], s[len - i]);
s[len + 1] = '\0';
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n, ans = 0;
node *root = new node();
memset(get, 0, sizeof(get));
scanf("%d", &n);
while(n--)
{
scanf("%s", s);
Insert(root, s);
}
AC_Automation(root);
scanf("%s", get);
int num = 0, i = 0, l = strlen(get);
while(i < l)
{
if(get[i] <= 'Z' && get[i] >= 'A')
text[num++] = get[i++];
else if(get[i] == '[')
{
i++;
int len = 0;
while(get[i] >= '0' && get[i] <= '9')
len = 10 * len + (get[i++] - '0');
for(int j = 0; j < len; j++)
text[num++] = get[i];
i += 2;
}
}
text[num] = '\0';
ans += Query(root, text);
reverse(text);
ans += Query(root, text);
printf("%d\n", ans);
}
}HDU 3695 Computer Virus on Planet Pandora (AC自动机)
原文地址:http://blog.csdn.net/tc_to_top/article/details/44103003