思路分析:
重要的是query 的时候 ,如果str 的当前字符不是大写字母的话,就要直接让p指向root ,数组只能开26 而不能开完ascii码。不然会MLE
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int max_next = 26;
char TAB = 'A';
struct trie
{
struct trie *fail;
struct trie *next[max_next];
int count;
};
trie *Q[500005];
int head,tail;
char str[2000005];
void insert(trie *root,char *word,int id)
{
trie *p=root;
int i=0;
while(word[i]!='\0')
{
if(p->next[word[i]-TAB]==NULL)
{
trie *temp = new trie;
for(int j=0;j<max_next;j++)temp->next[j]=NULL;
temp->count=0;
temp->fail=NULL;
p->next[word[i]-TAB]=temp;
}
p=p->next[word[i]-TAB];
i++;
}
p->count=id;
}
void acbuild(trie *root)
{
root->fail=NULL;
head=tail=0;
Q[tail++]=root;
while(head<tail)
{
trie *temp=Q[head++];
trie *p=NULL;
for(int i=0;i<max_next;i++)
{
if(temp->next[i]!=NULL)
{
if(temp==root)temp->next[i]->fail=root;
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)temp->next[i]->fail=root;
}
Q[tail++]=temp->next[i];
}
}
}
}
int ans[2222222];
int top;
int CNT[2222];
bool query(trie *root)
{
int i=0;
bool cnt=0;
int len=strlen(str);
trie *p=root;
int index;
while(str[i])
{
int index = str[i]-TAB;
if(index>25 || index<0)
{
p=root;
i++;
continue;
}
while(p->next[index]==NULL && p!=root)
p=p->fail;
p=p->next[index];
if(p==NULL)p=root;
trie *temp=p;
while(temp!=NULL)
{
if(temp->count)ans[top++]=temp->count;
cnt=true;
//cnt+=temp->count;
//temp->count=0;
temp=temp->fail;
}
i++;
}
return cnt;
}
void del(trie *root)
{
for(int i=0;i<max_next;i++)
if(root->next[i])del(root->next[i]);
free(root);
}
char word[1005][55];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
trie *root = new trie;
for(int i=0;i<max_next;i++)root->next[i]=NULL;
root->count=0;
root->fail=NULL;
for(int i=1;i<=n;i++)
{
scanf("%s",word[i]);
insert(root,word[i],i);
}
acbuild(root);
scanf("%s",str);
top=0;
query(root);
//cout<<"---"<<endl;
memset(CNT,0,sizeof CNT);
for(int i=0;i<top;i++)
CNT[ans[i]]++;
for(int i=1;i<=n;i++)
{
if(CNT[i])printf("%s: %d\n",word[i],CNT[i]);
}
}
return 0;
}
/*
3
aaa
bbb
ccc
2
bbbaacc
aaabbbcccbbb
*/