看了几天居然连后缀自动机的构造原理和性质都没完全搞懂。。。更不用说应用了。
在这里膜一下先辈CLJ大神(的PPt),大神的世界就是不懂。另外还要膜一下国家集训队的几篇论文作者,表示还没看懂orz
先贴一个讲得通俗易懂的后缀自动机学习网站(蒟蒻的我居然仍然没看懂),讲得也够详细。学习网站
苦逼的我·一个下午就死记硬背了这篇代码。感觉:看代码比看论文里的长篇大论简单多了(我是蒟蒻)。
代码贴上(终于背下来了):
1 #include<cstdio> 2 #include<string.h> 3 #define maxn 100000 4 #define Len 10000 5 using namespace std; 6 7 struct suffix_automaton 8 { 9 struct sufnode 10 { 11 long son[26],pre,len; 12 }suf[maxn]; 13 long last,tot; 14 char s[Len]; 15 16 inline void push(long len) 17 { 18 suf[++tot].len=len,suf[tot].pre=0; 19 memset(suf[tot].son,0,sizeof(suf[tot].son)); 20 } 21 22 void Extend(char cc) 23 { 24 long q,nq,p,np; 25 push(suf[last].len+1); 26 p=last,np=tot; 27 for(;!suf[p].son;p=suf[p].pre)suf[p].son[ch]=np; 28 if (!p)suf[np].pre=0; 29 else { 30 q=suf[p].son[ch]; 31 if (suf[q].len!=suf[p].len+1){ 32 push(suf[p].len+1); 33 nq=tot; 34 memcpy(suf[nq].son,suf[q].son,sizeof(suf[q].son)); 35 suf[nq].pre=suf[q].suf; 36 suf[q].pre=suf[np].pre=nq; 37 for (;suf[p].son[ch]==q;p=suf[p].pre)suf[p].son[ch]=nq; 38 } else suf[np].pre=q; 39 } 40 last=np; 41 } 42 43 void Build() 44 { 45 long i,len; 46 scanf("%s",s); 47 tot=last=0; 48 for (i=0,len=s.size();i<len;i++)Extend(s[i]-‘A‘); 49 } 50 }suf;
下面是CLJ的PPT
时间: 2024-09-30 00:27:22