多串匹配,AC自动机
建出fail树,那么一个点就对他的祖先产生贡献,每个点维护子树内的权值和,然后每个串的出现次数就是自动机上对应的点的值
好像讲的不清不楚
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
void up(int &x,int y){if(y>x)x=y;}
void down(int &x,int y){if(y<x)x=y;}
const int maxn = 210;
const int maxl = 1001000;
struct trie
{
int c[26],s,fail;
}tr[1100000]; int root=0,tot;
int n,t[maxn];
int newtr()
{
tot++;
tr[tot].fail=tr[tot].s=0;
memset(tr[tot].c,0,sizeof tr[tot].c);
return tot;
}
void ins(char *s,int x)
{
int nw=root;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int j=s[i]-'a';
if(!tr[nw].c[j]) tr[nw].c[j]=newtr();
nw=tr[nw].c[j];
tr[nw].s++;
}
t[x]=nw;
}
int q[1100000],head,tail;
void build_()
{
q[head=tail=1]=root;
while(head<=tail)
{
int x=q[head++];
for(int i=0;i<26;i++)
{
int &y=tr[x].c[i];
if(y)
{
if(x==root) tr[y].fail=0;
else tr[y].fail=tr[tr[x].fail].c[i];
q[++tail]=y;
}
else y=tr[tr[x].fail].c[i];
}
}
for(int i=tail;i;i--) tr[tr[q[i]].fail].s+=tr[q[i]].s;
}
char str[maxl];
int main()
{
tot=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",str);
ins(str,i);
}
build_();
for(int i=1;i<=n;i++) printf("%d\n",tr[t[i]].s);
return 0;
}