1. 程式人生 > >使用後綴自動機求後綴數組

使用後綴自動機求後綴數組

得到 後綴自動機 數組 color 後綴 bit == %d mes

倒序建立後綴自動機的fail樹就是後綴樹,dfs後綴樹得到後綴數組

#include <bits/stdc++.h>
using namespace std;

  int last,dis[200001],val[200001],cnt,a[200001][26],fa[200001],sa[200001],n,sta[200001],top;
  int tr[200001][26],rank[200001],height[200001];
  char st[200001];

  void ins(int num,int pos){
      int p=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{ int q=a[p][num]; if (dis[p]+1==dis[q]) fa[np]=q;else{ int nq=++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]; } } } void dfs1(int po){ for (int i=0;i<26;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];//確定後綴樹的出邊 dfs1(a[po][i]); top
--; } } void dfs2(int po){ if (val[po]) sa[++cnt]=val[po]; for (int i=0;i<26;i++) if (tr[po][i]) dfs2(tr[po][i]); } void getheight(){ int k=0; int po1,po2; for (int i=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; } } int main(){ scanf("%s",st+1); n=strlen(st+1); last=cnt=1; for (int i=n;i>=1;i--) ins(st[i]-a,i); dfs1(1); cnt=0; dfs2(1); for (int i=1;i<=n;i++) rank[sa[i]]=i; getheight(); for (int i=1;i<=n;i++) printf("%d ",sa[i]);printf("\n"); for (int i=1;i<n;i++) printf("%d ",height[i]); }

使用後綴自動機求後綴數組