zoukankan      html  css  js  c++  java
  • 使用后缀自动机求后缀数组

    倒序建立后缀自动机的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("
    ");
        for (int i=1;i<n;i++) printf("%d ",height[i]);
      }
  • 相关阅读:
    layer-list:Android中layer-list使用详解
    Nexus6p:正在下载系统更新,没有进度
    转:浅谈char类型范围
    C/C++/Java中的volatile关键字
    C++中的mutable关键字
    C++中的typedef typename 作用
    C++中的友元函数和友元类
    用flashfxp做ftp镜像同步
    python读取caffemodel文件
    py-faster-rcnn几个辅助脚本
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/7999381.html
Copyright © 2011-2022 走看看