[TJOI2013]单词


  • 题意:给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