当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
但
网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的
网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t
收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的
网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
web 1: 1 2 3
total: 1
裸的AC自动机
code:
#include<iostream>
using namespace std;
struct tree
{
tree *fail,*next[128];
int cnt;
}*root,*p;
tree arr[1000001];
int index,n, m;
tree *que[1000001];
char let=0;
void newn()
{
arr[index].cnt=0;
for(int i=0;i<128;i++) arr[index].next[i]=0;
arr[index].fail=NULL;
}
void insert(char ch[],int w)
{
p=root;
int i=0,tmp;
while(ch[i])
{
tmp=ch[i]-let;
if(p->next[tmp]==0)
{
newn();
p->next[tmp]=&arr[index++];
}
p=p->next[tmp];
i++;
}
p->cnt = w;
}
void get_fail()
{
tree *q;
p=root; p->fail=root;
int open=-1,close=-1,i;
for(i=0;i<128;i++)
{
if(p->next[i]==0) p->next[i]=root;
else
{
p->next[i]->fail=root;
open++;
que[open]=p->next[i];
}
}
while(close<open)
{
close++;
q=que[close];
for(i=0;i<128;i++)
{
if(q->next[i]==0) q->next[i]=q->fail->next[i];
else
{
q->next[i]->fail=q->fail->next[i];
open++;
que[open]=q->next[i];
}
}
}
}
int a[5], len;
int query(char ch[])
{
int num=0;
p=root;
tree *q;
int tmp,i=0;
len = -1;
a[0] = a[1] = a[2] = -1;
while(ch[i])
{
tmp=ch[i]-let;
p=p->next[tmp];
q=p;
while(q->cnt)
{
if(q->cnt != a[0] && q->cnt != a[1] && q->cnt != a[2])
{
len ++;
a[len] = q->cnt;
}
//q->cnt=0;
q=q->fail;
}
i++;
}
return len;
}
char s[10005];
int main()
{
int t;
while(scanf("%d",&n) != EOF)
{
getchar();
int i;
index=0;
newn();
root=&arr[index++];
char ch[201];
for(i=1;i<=n;i++)
{
gets(ch);
insert(ch,i);
}
get_fail();
scanf("%d",&m);getchar();
int cnt = 0;
for(i = 1;i <= m; i ++)
{
gets(s);
int tmp = query(s);
if(tmp >= 0)
{
int j, k;
cnt ++;
printf("web %d:",i);
for(j = 0; j <= tmp; j ++)
for(k = j+1;k<=tmp; k ++)
if(a[j] > a[k]) swap(a[j],a[k]);
for(j=0;j<=tmp;j++) printf(" %d",a[j]); putchar('\n');
}
}
printf("total: %d\n",cnt);
}
}