题目意思是用主串去匹配模式串,如果a和b都在主串中出现了且a是b的子串,这只算b,求出能够匹配的模式串。
我的超时代码,不知道为什么就能超时。。。
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int CH=26;
const int NODE=6100000;
int chd[NODE][CH],fail[NODE],word[NODE],sz;
char s1[6100010],s2[6100010];
bool vis[3100];
void Ins(char *s,int val)
{
int p=0;
for(;*s;s++)
{
int id=(*s)-'A';
if(!chd[p][id])
{
memset(chd[sz],0,sizeof(chd[sz]));
word[sz]=0;
chd[p][id]=sz++;
}
p=chd[p][id];
}
word[p]=val;
}
int Que[NODE];
void AC()
{
int *s=Que,*e=Que;
for(int i=0;i<CH;i++)
if(chd[0][i]){
*e++=chd[0][i];
fail[chd[0][i]]=0;
}
while(s!=e)
{
int p=*s++;
for(int i=0;i<CH;i++)
if(chd[p][i])
{
int k=chd[p][i];
fail[k]=chd[fail[p]][i];
*e++=chd[p][i];
}
else
chd[p][i]=chd[fail[p]][i];
}
}
void change(char *s)
{
int num=0;
for(;*s;s++)
if((*s)=='[')
{
s++;
int cnt=(*s++)-'0';
while((*s)>='0'&&(*s)<='9') cnt=cnt*10+(*s)-'0',s++;
for(int i=0;i<cnt;i++) s2[num++]=(*s);
s++;
}
else s2[num++]=(*s);
s2[num]='\0';
}
void solve()
{
int p=0;
for(int i=0;s2[i];i++)
{
p=chd[p][s2[i]-'A'];
for(int tmp=fail[p];tmp>0&&word[tmp]>=0;tmp=fail[tmp])
if(word[tmp]>0)
{
vis[word[tmp]]=1,word[tmp]=-1;
break;
}
}
}
char ss[2510][1200];
void Ins1(char *s,int val)
{
int p=0;
for(;*s;s++)
{
int id=(*s)-'A';
if(!chd[p][id])
{
memset(chd[sz],0,sizeof(chd[sz]));
word[sz]=0;
chd[p][id]=sz++;
}
p=chd[p][id];
if(word[p]>0) vis[word[p]]=0;
}
word[p]=val;
}
void AC1()
{
int *s=Que,*e=Que;
for(int i=0;i<CH;i++)
if(chd[0][i])
{
*e++=chd[0][i];
fail[chd[0][i]]=0;
}
while(s!=e)
{
int p=*s++;
for(int i=0;i<CH;i++)
if(chd[p][i])
{
int k=chd[p][i];
fail[k]=chd[fail[p]][i];
for(int tmp=fail[k];tmp>0;tmp=fail[tmp])
if(word[tmp]>=0) vis[word[tmp]]=0,word[tmp]=-1;
else break;
*e++=chd[p][i];
}
else
chd[p][i]=chd[fail[p]][i];
}
}
int main()
{
int ca,n;
scanf("%d",&ca);
while(ca--)
{
scanf("%d",&n);
getchar();
sz=1;
memset(chd[0],0,sizeof(chd[0]));
for(int i=0;i<n;i++)
{
scanf("%s",ss[i]);
change(ss[i]);
Ins(s2,i+1);
}
AC();
memset(vis,0,sizeof(vis));
scanf("%s",s1);
change(s1);
solve();
sz=1;
memset(chd[0],0,sizeof(chd[0]));
for(int i=0;i<n;i++)
if(vis[i+1]) Ins1(ss[i],i+1);
AC1();
int ans=0;
for(int i=1;i<=n;i++) if(vis[i]) ans++;
printf("%d\n",ans);
}
return 0;
}
/*
4
3
[2F]RR
RR
R
[4F]RRE
*/