SAM, i.e. suffix automaton, suffix automaton.
There are many ways to play strings, and there are many algorithms that are expanded around strings. Why? My understanding is that the number of elements in each unit of a sequence of letters consists of a finite number compared to a sequence of numbers. For finite things, there are some wonderful properties compared to infinite things. The simplest is that the number of sons of each node of the tree that the sequence expands into is limited. So according to this, from the string hash, to KMP, and then to Suffix Array,suffix automaton, have been born.
The suffix array in the processing string is equivalent to a good steel, he can cope with most problems in the string. So why learn Sam, very simple. Sam is very useful, and very short. Elegant and useful, this is the reason to learn.
If you don't say it's useless, it's not easy to write, and you can construct a suffix array directly.
Specific details do not delve into, make Oi talk practical, so here face value talk about the structure and application, mainly to the problem.
Structure
As we all know, the suffix array is dejected and the constants are quite large. But Sam is good to be able to construct it online .
First put the code:
struct Sam{int pre[maxn],son[maxn][26],cnt,len,now,step[maxn],np,nq,p,q; SAM () {memset (pre,0,sizeof (pre)); Memset (Son,0,sizeof (son)); cnt=1;len=0;now=1;} void Extend (int nxt) {p=now;np=++cnt;step[np]=step[now]+1;now=np;while (p&&!son[p][nxt]) {son[p][nxt]=np;p= PRE[P];} if (!p) pre[np]=1;else{q=son[p][nxt];if (step[q]==step[p]+1) pre[np]=q;else{step[(nq=++cnt)]=step[p]+1;memcpy (son[ Nq],son[q],sizeof (Son[q]));p Re[nq]=pre[q];p re[np]=pre[q]=nq;while (p&&son[p][nxt]==q) {son[p][nxt]=nq;p= PRE[P];}}} int Walk (int nxt) {while (!son[now][nxt]&&pre[now]) {Now=pre[now]; Len=step[now];} if (!SON[NOW][NXT]) return 0;NOW=SON[NOW][NXT]; Len++;return Len; void Build () {scanf ("%s", s+1), int len=strlen (s+1); up (I,1,len) Extend (s[i]-' a ');}} Sam
A preliminary study of Sam