世界真的很大
日常被数组坑233
感觉怎么也调不出来的时候就去看一下是不是空间的问题吧。。
HDU的题日常多组数据。。
每组数据用完不清零基本上MLE
看题先:
description:
给出很多个模式串,问在文章里有几个模式串,(反过来的模式串也算)出现过
文章里有时会有形如[n X]的东西,n是数字,X是字符,表示这个位置有n个X字符
n不一定是一位数
input:
多组数据,每组数据开头一个数字n,表示有n个模式串
接下来n行,每行一个模式串
然后一个字符串给出文章
output:
每组数据一个数字表示有都是个模式串出现过
基本上还算是AC自动机的裸题,为了复习AC自动机的写法去做的,却意外的调了半天,忽然觉得还是写一下比较好
首先考虑怎么处理模式串反过来也算的问题
就直接反过来再插入就好
但是这两个串都出现也只能算一个串出现了,所以考虑给trie树里面每个串打标记,标记其属于哪个模式串
然后处理文章里面[]的问题。
还是比较简单,注意一下细节就好
数组记得开大一点,字符串开5100010
我就是数组开小了,WA了半天。。他不RE,WA。。
完整代码:
#include<stdio.h>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct node
{
node *fail;
node *nxt[26];
int cnt,mrk,idc;
}pool[10000010],*tail=pool,*root;
int n,T,vis[8000010];
char t[5100010],ss[5100010],sss[5100010];
node *newnode()
{
node *nd=++tail;
memset(nd->nxt,0,sizeof(nd->nxt));
nd->fail=0;
nd->cnt=nd->mrk=nd->idc=0;
return nd;
}
void init()
{
memset(ss,0,sizeof(ss));
memset(t,0,sizeof(t));
memset(sss,0,sizeof(sss));
memset(vis,0,sizeof(vis));
tail=pool;
root=newnode();
}
void insert(char *s,int id)
{
int len=strlen(s);
node *p=root;
for(int i=0;i<len;i++)
{
int k=s[i]-'A';
if(!p->nxt[k])
p->nxt[k]=newnode();
p=p->nxt[k];
}
p->cnt++;
p->idc=id;
}
void build()
{
queue <node*> state;
state.push(root);
root->fail=0;
while(!state.empty())
{
node *tmp=state.front(),*p=0;
state.pop();
for(int i=0;i<26;i++)
if(tmp->nxt[i])
{
if(tmp==root) tmp->nxt[i]->fail=root;
else
{
p=tmp->fail;
while(p)
{
if(p->nxt[i])
{
tmp->nxt[i]->fail=p->nxt[i];
break ;
}
p=p->fail;
}
if(!p) tmp->nxt[i]->fail=root;
}
state.push(tmp->nxt[i]);
}
}
}
void trans(char *s)
{
int i;
int j=0,num=0;
for(i=0;s[i];i++){
if('A'<=s[i] && s[i]<='Z')
ss[j++] = s[i];
else if( '0'<=s[i] && s[i]<='9')
num = num*10 + int(s[i]-'0');
else if( s[i]==']' )
while(--num)
ss[j++] = s[i-1];
}
ss[j] = '\0';
}
void query(char *s)
{
int cnt=0,k,len=strlen(s);
node *p=root;
for(int i=0;i<len;i++)
{
k=s[i]-'A';
while(!p->nxt[k] && p!=root) p=p->fail;
p=p->nxt[k];
if(!p) p=root;
node *tmp=p;
while(tmp!=root&& !tmp->mrk)
{
tmp->mrk=1;
if(tmp->idc>0) vis[tmp->idc]=1;
tmp=tmp->fail;
}
}
}
int getans()
{
int rt=0;
for(int i=1;i<=n;i++)
rt+=vis[i];
return rt;
}
int main()
{
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",t);
insert(t,i);
reverse(t,t+strlen(t));
insert(t,i);
}
build();
scanf("%s",sss);
trans(sss);query(ss);
printf("%d\n",getans());
}
return 0;
}
/*
Whoso pulleth out this sword from this stone and anvil is duly born King of all England
*/
嗯,就是这样