- 题意:给n个字符串,问每个字符串在所有串里出现几次。
- 思路:判断一个整串与其它串之间的包含关系通常用AC自动机。fail树是我们想象中的树,但是它可以帮助我们更好的理解AC自动机。
1.fail树上的每个前缀都对应fail树里面的节点。通常节点存cnt[]表示有多少个串经过该点(即多少个前缀)
2.fail树中祖先节点是子孙节点的后缀,其中父亲是最长严格后缀。反过来,每个节点是它的子树里面节点的后缀。
通常一个串包含于另一个串我们理解为:一个串是另一个串的前缀的后缀。(因为前缀是节点,后缀在fail树上有意义)
当然这道题直接求FAIL树中该节点子树的cnt和。
- easy code:
#include
using namespace std;
const int N=1e6+5;
char s[N];
int pos[N],n;
struct AC {
int fail[N],nd,go[N][27],cnt[N],Q[N],hd,tl,st[N],tp;
bool mark[N];
AC() {nd=tl=0;hd=1;}
void Insert(int &u) {
u=0;
int sz=strlen(s);
for(int i=0;i