【uoj35】 后缀排序
http://uoj.ac/problem/35 (题目链接)
题意
如题,并且求height数组。
Solution
挂一发后缀自动机构后缀数组及height数组
细节
注意基数排序和连边的时候不要把根节点也算进去
代码
// uoj35 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define LL long long #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=100010; int sa[maxn],height[maxn]; char s[maxn]; namespace SAM { int par[maxn<<1],len[maxn<<1],r[maxn<<1],ch[maxn<<1][26],pos[maxn<<1]; int last,sz,Dargen,n,cnt; int b[maxn],id[maxn<<1],head[maxn<<1]; struct edge {int to,next;}e[maxn<<2]; void link(int u,int v) { e[++cnt]=(edge){v,head[u]};head[u]=cnt; } void Extend(int c) { int np=++sz,p=last;last=np; pos[np]=len[np]=r[np]=len[p]+1; for (;p && !ch[p][c];p=par[p]) ch[p][c]=np; if (!p) par[np]=Dargen; else { int q=ch[p][c]; if (len[p]+1==len[q]) par[np]=q; else { int nq=++sz; len[nq]=len[p]+1;r[nq]=r[q]; memcpy(ch[nq],ch[q],sizeof(ch[q])); par[nq]=par[q]; par[np]=par[q]=nq; for (;p && ch[p][c]==q;p=par[p]) ch[p][c]=nq; } } } void build() { last=sz=Dargen=1; n=strlen(s+1); for (int i=1;i<=n>>1;i++) swap(s[i],s[n-i+1]); for (int i=1;i<=n;i++) Extend(s[i]-'a'); } void dfs(int x,int l) { if (pos[x]) sa[++sz]=n-pos[x]+1,height[sz]=l; for (int i=head[x];i;i=e[i].next) { if (i==head[x]) dfs(e[i].to,pos[x] ? len[x] : l); else dfs(e[i].to,len[x]); } } void pre() { for (int i=1;i<=sz;i++) b[s[r[i]-len[par[i]]]-'a']++; for (int i=1;i<=26;i++) b[i]+=b[i-1]; for (int i=2;i<=sz;i++) id[b[s[r[i]-len[par[i]]]-'a']--]=i; for (int i=sz-1;i>=1;i--) link(par[id[i]],id[i]); sz=0;dfs(1,0); } } using namespace SAM; int main() { scanf("%s",s+1); build(); pre(); for (int i=1;i<=n;i++) printf("%d ",sa[i]); puts(""); for (int i=2;i<=n;i++) printf("%d ",height[i]); return 0; }
This passage is made by MashiroSky.