int idx(char s){return s-'a';}
void insert(char s[])
{
int len=strlen(s);
int now=root;
for(int i=0;i<len;i++)
{
int id=idx(s[i]);
if(!c[now][id]) c[now][id]=cnt++;
now=c[now][id];
}
val[now]++;
}
void build()
{
for(int i=0;i<26;i++)
if(c[root][i])
{
fail[c[root][i]]=root;//根的每一个子节点的fail都指向根
q.push(c[root][i]);//队列中的节点代表存在且没有初始化其子节点fail的节点
}
while(!q.empty())
{
int now=q.front();q.pop();//取出队首节点
for(int i=0;i<26;i++)
{
if(c[now][i])//如果儿子i存在
{
fail[c[now][i]]=c[fail[now]][i];
q.push(c[now][i]);
}
else c[now][i]=c[fail[now]][i];//如果儿子i不存在,就连一条虚拟的边
}
}
}
int Query(char s[])
{
int len=strlen(s);
int now=root;
int ans=0;
for(int i=0;i<len;i++)
{
int id=idx(s[i]);
now=c[now][id];
for(int t=now;t && ~val[t];t=fail[t]) ans+=val[t],val[t]=-1;
}
return ans;
}
07-24
07-24