看了几天居然连后缀自动机的构造原理和性质都没完全搞懂。。。更不用说应用了。
在这里膜一下先辈CLJ大神(的PPt),大神的世界就是不懂。另外还要膜一下国家集训队的几篇论文作者,表示还没看懂orz
先贴一个讲得通俗易懂的后缀自动机学习网站(蒟蒻的我居然仍然没看懂),讲得也够详细。学习网站
苦逼的我·一个下午就死记硬背了这篇代码。感觉:看代码比看论文里的长篇大论简单多了(我是蒟蒻)。
代码贴上(终于背下来了):
1 #define N 10000 2 3 struct suffix_automaton 4 { 5 struct node 6 { 7 long son[26],pre,len; 8 }t[N]; 9 long tot,root,last; 10 11 inline long Newnode(long len) 12 { 13 t[++tot].len=len; 14 memset(t[tot].son,-1,sizeof(t[tot].son)); 15 return tot; 16 } 17 18 inline void update(long pla) 19 { 20 long p,np,q,nq; 21 p=last,np=Newnode(t[last].len+1); 22 while (p>-1&&t[p].son[pla]==-1){ 23 t[p].son[pla]=np; 24 p=t[p].pre; 25 } 26 if (p==-1)t[np].pre=root; 27 else { 28 q=t[p].son[pla]; 29 if (t[q].len==t[p].len+1)t[np].pre=q; 30 else { 31 nq=Newnode(t[p].len+1); 32 memcpy(t[nq].son,t[q].son,sizeof(t[q].son)); 33 t[nq].pre=t[q].pre,t[q].pre=t[np].pre=nq; 34 while (p>-1&&t[p].son[pla]==q){ 35 t[p].son[pla]=nq; 36 p=t[p].pre; 37 } 38 } 39 } 40 last=np; 41 } 42 43 void Build(char s[]) 44 { 45 long i,len; 46 tot=-1; 47 root=last=Newnode(0); 48 t[root].pre=-1; 49 for (i=0,len=strlen(s);i<len;i++)update(s[i]-'a'); 50 } 51 };
下面是CLJ的PPT
8.10终于搞懂构造方法了。。其实很简单orz。只是要了解性质的话还需动动脑子。