The fail tree that establishes the suffix automaton in reverse is the suffix tree, and the Dfs suffix tree gets the suffix array
#include <bits/stdc++.h>using namespacestd; intlast,dis[200001],val[200001],cnt,a[200001][ -],fa[200001],sa[200001],n,sta[200001],top; inttr[200001][ -],rank[200001],height[200001]; Charst[200001]; voidInsintNumintPOS) { intp=last,np=last=++CNT; DIS[NP]=dis[p]+1; val[np]=POS; while(!a[p][num]&&p) a[p][num]=np,p=Fa[p]; if(!p) fa[np]=1;Else{ intq=A[p][num]; if(dis[p]+1==DIS[Q]) fa[np]=q;Else{ intnq=++cnt;dis[nq]=dis[p]+1; memcpy (A[nq],a[q],sizeof(A[q])); FA[NQ]=Fa[q]; FA[Q]=fa[np]=NQ; while(a[p][num]==q) a[p][num]=nq,p=Fa[p]; } } } voidDFS1 (intPO) { for(intI=0;i< -; i++) if(a[po][i]&&dis[a[po][i]]==dis[po]+1) {sta[++top]=i; Tr[fa[a[po][i]]][sta[dis[a[po][i]]-dis[fa[a[po][i]]]]]=a[po][i];//Determining the DFS1 (A[po][i]) of the suffix tree; Top--; } } voidDFS2 (intPO) { if(Val[po]) sa[++cnt]=Val[po]; for(intI=0;i< -; i++) if(Tr[po][i]) DFS2 (Tr[po][i]); } voidgetheight () {intk=0; intPo1,po2; for(intI=1; i<=n;i++) {PO1=i,po2=sa[rank[i]-1]; if(k) k--; while((St[po1+k]==st[po2+k]) && (po1+k<=n) && (po2+k<=N)) K++; Height[rank[i]-1]=K; } } intMain () {scanf ("%s", st+1); N=strlen (st+1); Last=cnt=1; for(inti=n;i>=1; i--) ins (St[i]-'a', i); DFS1 (1); CNT=0; DFS2 (1); for(intI=1; i<=n;i++) rank[sa[i]]=i; GetHeight (); for(intI=1; i<=n;i++) printf ("%d", Sa[i]);p rintf ("\ n"); for(intI=1; i<n;i++) printf ("%d", Height[i]); }
Using suffix automata to find suffix arrays