hdu3065 病毒侵袭持续中(AC自动机模板题)

题目

给一些模式串,一个标准串

统计每个串的出现次数

注意模式串中只有大写字母

标准串可见字符啥都有

思路来源

https://www.cnblogs.com/gongxijun/p/4018255.html

https://www.cnblogs.com/Simon-X/p/5687318.html

心得

开始忘了memsetTrie树,然后疯狂tle???

卧槽我该剪枝的都减了啊……

其实就一处,<'A'或>'Z'的直接回root就行了,

毕竟这种情况下按下标访问是会越界的……

然后发现了,把最开始的代码一改,A了...

代码

#include
#include
#include
#include
using namespace std;
struct node
{
  int id,fail,Next[26],sum;       
}trie[50005];
char s[1005][55],web[2000005];
int que[50005];//建ac自动机的队列 
int root,tot;//根的编号 节点编号 
bool ok[1005];//i病毒是否出现 
int t,n,res[1005],ans[1005],cnt;
void insert(int r,char *s,int id)//(root,串,串号),trie树插入 
{
   int len=strlen(s);
   for(int i=0;i'Z')//暴力剪枝 
     	{
     		r=root;
     		continue;
     	}
        while(trie[r].Next[s[i]-65]==0&&r!=root)r=trie[r].fail;  
         r=trie[r].Next[s[i]-65];//可以向后走就向后走,从root向后走也行,否则就是root; 
         if(!r)r=root;
		 for(int tempfail=r;tempfail!=root;tempfail=trie[tempfail].fail)//对自动机上的一段类似KMP 
         {                                      
            if(trie[tempfail].id>0)//暴力统计好了 搞一个内部子串的缀和貌似也挺麻烦的
			{
			 if(!res[trie[tempfail].id])ans[cnt++]=trie[tempfail].id;
			 res[trie[tempfail].id]++;
			}
         }
     }
}
void init()
{
	tot=cnt=0;
	root=++tot;
	memset(res,0,sizeof res);
	memset(trie,0,sizeof trie);
}
int main()
{
    while(~scanf("%d",&n))
    {
    init();   
    for(int i=0;i

 

你可能感兴趣的:(hdu3065 病毒侵袭持续中(AC自动机模板题))