char str1[5100009], str2[5100009];
int cnt;
struct trie
{
trie *ch[26];
trie *fail;
int end;
void init()
{
memset(ch, NULL, sizeof(ch));
fail = NULL;
end = 0;
}
}*root, t[maxn];
void insert(char *s)
{
trie *p = root;
for(int i=0; s[i]; i++)
{
//cout<<i<<' '<<s[i]<<endl;
int k = s[i]-'A';
if(p->ch[k]==NULL)
{
t[cnt].init();
p->ch[k] = &t[cnt++];
}
p = p->ch[k];
}
p->end = 1;
}
queue<trie*>q;
void build_fail()
{
q.push(root);
root->fail = root;
while(!q.empty())
{
trie *p = q.front();
q.pop();
for(int k=0; k<26; k++)
if(p->ch[k]!=NULL)
{
q.push(p->ch[k]);
if(p==root)
{
p->ch[k]->fail = root;
continue;
}
trie *tmp = p->fail;
while( tmp!=root && tmp->ch[k]==NULL)
tmp = tmp->fail;
if(tmp->ch[k]) p->ch[k]->fail = tmp->ch[k];
else p->ch[k]->fail = root;
}
}
}
int query(char *a)
{
int ans = 0;
trie *p = root;
for(int i=0; a[i]; i++)
{
if(a[i]<'A' || a[i]>'Z')
{
p = root;
continue;
}
int k = a[i]-'A';
while(p->ch[k]==NULL && p!=root) p=p->fail;
p = p->ch[k];
p = (p==NULL)? root : p;
trie *tmp = p;
while(tmp!=root && tmp->end!=0)
{
ans++;
tmp->end = 0;
tmp = tmp->fail;
}
}
return ans;
}
int main()
{
int tt, n, i, j;
scanf("%d", &tt);
while(tt--)
{
cnt = 1;
t[0].init();
root = &t[0];
scanf("%d", &n);
while(n--)
{
scanf("%s", str1+1);
for(i=1, j=1; str1[i]; i++)
{
if(str1[i]>='A' && str1[i]<='Z') str2[j++] = str1[i];
else
{
i++;
int k = str1[i]-'0';
i++;
while(str1[i]>='0'&&str1[i]<='9') k = k*10+ str1[i++]-'0';
while(k--) str2[j++] = str1[i];
i++;
}
}
str2[j] = '\0';
insert(str2+1);
}
build_fail();
scanf("%s", str1+1);
for(i=1, j=1; str1[i]; i++)
{
if(str1[i]>='A' && str1[i]<='Z') str2[j++] = str1[i];
else
{
i++;
int k = str1[i]-'0';
i++;
while(str1[i]>='0'&&str1[i]<='9') k = k*10+ str1[i++]-'0';
while(k--) str2[j++] = str1[i];
i++;
}
}
str2[j] = '\0';
//cout<<str2+1<<endl;
int ans = query(str2+1);
for(i=1, j=strlen(str2+1); i<j; i++, j--)
swap(str2[i], str2[j]);
ans += query( str2+1 );
printf("%d\n", ans);
}
return 0;
}
HDU-3695-ac自动机
最新推荐文章于 2019-07-24 09:24:46 发布