zoukankan      html  css  js  c++  java
  • 【模板】后缀数组

     注意x,y数组的意义

    x[i]表示编号为i的后缀的第一关键字

    y[i]表示第二关键字排名为i的后缀编号

    h[i]表示编号为i的后缀与其前一名的最大公共前缀

    height[i]表示排名为i的后缀与其前一名的最大公共前缀

    h[i]>=h[i-1]-1

    代码打的比较丑,有时间重新打一遍

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=2000010;
     4 int n,s[N];
     5 int m,x[N],y[N],sa[N],cnt[N],rank[N];
     6 int h[N],height[N];
     7 char ss[N];
     8 void build_sa(){
     9     for(int i=0;i<n;i++) cnt[x[i]]++;
    10     for(int i=1;i<m;i++) cnt[i]+=cnt[i-1];
    11     for(int i=n-1;~i;i--) sa[--cnt[x[i]]]=i;
    12     for(int i=0;i<m;i++) cnt[i]=0;
    13     for(int k=1;k<=n;k<<=1){
    14         int num=0;
    15         for(int i=n-1;i>=n-k;i--) y[num++]=i;
    16         for(int i=0;i<n;i++) if(sa[i]>=k) y[num++]=sa[i]-k;
    17         for(int i=0;i<n;i++) cnt[x[i]]++;
    18         for(int i=1;i<m;i++) cnt[i]+=cnt[i-1];
    19         for(int i=n-1;~i;i--) sa[--cnt[x[y[i]]]]=y[i];
    20         for(int i=0;i<m;i++) cnt[i]=0;
    21         swap(x,y);
    22         num=0;
    23         x[sa[0]]=num;
    24         for(int i=1;i<n;i++){
    25             if(y[sa[i]]!=y[sa[i-1]]||y[sa[i-1]+k]!=y[sa[i]+k]) num++;
    26             x[sa[i]]=num;
    27         }
    28         num++;
    29         if(num>=n) break;
    30         m=num;
    31     }
    32     for(int i=0;i<n;i++) rank[sa[i]]=i;
    33     return;
    34 }
    35 void build_height(){
    36     int t=0;
    37     for(int i=0;i<n;i++){
    38         if(t) t--;
    39         if(!rank[i]) h[i]=0;
    40         else{
    41             while(s[i+t]==s[sa[rank[i]-1]+t]) t++;
    42             h[i]=t;
    43         }
    44         height[rank[i]]=h[i];
    45     }
    46     return;
    47 }
    48 int main(){
    49     scanf("%s",ss);
    50     n=strlen(ss);
    51     for(int i=0;i<n;i++){
    52         if(ss[i]>='0'&&ss[i]<='9') s[i]=ss[i]-'0';
    53         else if(ss[i]>='A'&&ss[i]<='Z') s[i]=ss[i]-'A'+10;
    54         else s[i]=ss[i]-'a'+36;
    55         x[i]=s[i];
    56     }
    57     m=62;
    58     build_sa();build_height();
    59     for(int i=0;i<n;i++) printf("%d ",sa[i]+1);
    60     printf("
    ");
    61     for(int i=1;i<n;i++) printf("%d ",height[i]);
    62     return 0;
    63 }
  • 相关阅读:
    Spark源码分析之-scheduler模块
    YARN
    java.lang.NoClassDefFoundError 怎么解决
    rdd
    Apache Spark探秘:三种分布式部署方式比较
    Sqrt函数的实现方法
    golang 自旋锁的实现
    支付宝往余额宝转钱怎么保证一致性
    mysql 面试题
    TCP 进阶
  • 原文地址:https://www.cnblogs.com/mycups/p/8557053.html
Copyright © 2011-2022 走看看