/*
把子串放进自动机里
母串在自动机里面走一遍 标记所有走到的节点和子串
子串去重 把子串的子串去掉就剩自己
*/
#include<stdio.h>
#include<string.h>
const int MM = 3000005,M1 = 26;
int N;
char s[2505][1105];
char ch[1105];
char str[5100005];
char tmp[5100005];
bool vis[2505];
bool flag[2505000];
int L;
int q[MM],front,last;
struct node{
int sign;
int fail;
int next[26];
}tree[MM];
void init(int p)
{
for(int i=0;i<M1;i++)
tree[p].next[i]=0;
tree[p].sign=tree[p].fail=0;
}
void insert(char s[],int id)
{
int i=0,p=0,x;
while(s[i])
{
x=s[i]-'A';
if(tree[p].next[x]==0)
{
tree[p].next[x]=++L;
init(L);
}
p=tree[p].next[x];
i++;
}
tree[p].sign=id;
}
void build( )
{
front = last = 0;
for(int i=0;i<M1;i++)
if(tree[0].next[i])
{
q[front++]=tree[0].next[i];
tree[tree[0].next[i]].fail=0;
}
while( last < front )
{
int t = q[last++];
for( int i = 0; i < M1; ++i )
{
int tt = tree[t].next[i];
int ff = tree[t].fail;
if( tree[t].next[i] )
{
tree[tt].fail = tree[ff].next[i];
q[front++] = tt;
}
else
tree[t].next[i] = tree[ff].next[i];
}
}
}
void AC( char str[] )
{
int i = 0,cur = 0;
while( str[i] )
{
int asc = str[i] - 'A';
cur = tree[cur].next[asc];
int p = cur;
while( p && !flag[p])
{
if(tree[p].sign)
vis[tree[p].sign]=1;
p = tree[p].fail;
flag[p]=1;
}
++i;
}
}
void Gao(char str[]){
int i=0,j,k;
int len=0;
while( str[i] )
{
if(str[i]=='['){
int tot=0;
i++;
while(str[i]>='0' && str[i]<='9'){
tot=tot*10+str[i]-'0';
i++;
}
while(tot){
tmp[len++]=str[i];
tot--;
}
i++;
}else{
tmp[len++]=str[i];
}
i++;
}
tmp[len]='\0';
strcpy(str,tmp);
}
int TW(){
int i,j,k;
for(i=1;i<=N;i++){
if(vis[i]){
int cur=0,asc=0;
j=0;
while(s[i][j]){
asc=s[i][j]-'A';
cur=tree[cur].next[asc];
int p=cur;
while(p && flag[p]){
flag[p]=0;
if(vis[tree[p].sign])
vis[tree[p].sign]=0;
p=tree[cur].fail;
}
j++;
}
vis[i]=1;
flag[cur]=1;
}
}
int ret=0;
for(i=1;i<=N;i++)
if(vis[i])
ret++;
return ret;
}
int main( )
{
int Case;
int i,j;
scanf( "%d",&Case );
while( Case-- )
{
scanf( "%d",&N );
L=0;
init(0);
for(i=1;i<=N;i++)
{
scanf( "%s",ch);
Gao(ch);
strcpy(s[i],ch);
insert( ch ,i );
}
build( );
scanf( "%s",str );
Gao(str);
memset(vis,0,sizeof(vis));
memset(flag,0,sizeof(flag));
AC(str);
printf( "%d\n",TW());
}
return 0;
}
Hrinity POJ
最新推荐文章于 2017-10-08 19:40:13 发布