zoukankan      html  css  js  c++  java
  • 后缀数组

    # 题意
    详细地说,给定一个长度为 n 的字符串S(下标 0~n-1),我们可以用整数 k(0≤k<n0≤k<n) 表示字符串S的后缀 S(k~n-1)。
    把字符串S的所有后缀按照字典序排列,排名为 i 的后缀记为 SA[i]。
    额外地,我们考虑排名为 i 的后缀与排名为 i-1 的后缀,把二者的最长公共前缀的长度记为 Height[i]。
    我们的任务就是求出SA与Height这两个数组。

    # 题解
    开始每个SA都是当前的下标
    定义比较函数是从两个后缀的公共长度后第一个字符的大小比较
    用二分求最长公共序列长度,
    因为是最长用最后一个元素的二分板子
    排序过后
    再依次输出字典序排在第 i 位的的后缀的开头下标
    已经他和他前面一个的最长公共序列长度

     1 #include <bits/stdc++.h>
     2 #define ull unsigned long long
     3 using namespace std;
     4 const int N=3e5+10,P=131;
     5 char s[N];
     6 int sa[N];
     7 ull h[N],p[N];
     8 int n;
     9 ull get(int l,int r){
    10    return h[r]-h[l-1]*p[r-l+1];
    11 }
    12 int get_lcp(int a,int b){
    13    int l=0,r=min(n-a+1,n-b+1);
    14    while(l<r){
    15       int mid=l+r+1>>1;
    16       if(get(a,a+mid-1) == get(b,b+mid-1))
    17          l=mid;
    18       else
    19          r=mid-1;
    20    }
    21    return l;
    22 }
    23 bool cmp(int a,int b){
    24    int len=get_lcp(a,b);
    25    int ava=a+len>n?INT_MIN:s[a+len];
    26    int bva=b+len>n?INT_MIN:s[b+len];
    27    return ava<bva;
    28 }
    29 int main(){
    30    ios::sync_with_stdio(0);
    31    cin.tie(0);
    32    cout.tie(0);
    33 
    34    scanf("%s",s+1);
    35    n=strlen(s+1);
    36    p[0]=1;
    37    for(int i=1;i<=n;i++){
    38       h[i]=h[i-1]*P+s[i]-'a'+1;
    39       p[i]=p[i-1]*P;
    40       sa[i]=i;
    41    }
    42    sort(sa+1,sa+n+1,cmp);
    43 
    44    for(int i=1;i<=n;i++)
    45       cout<<sa[i]-1<<' ';
    46    cout<<endl;
    47 
    48    for(int i=1;i<=n;i++){
    49       if(i==1)
    50          cout<<"0 ";
    51       else
    52          cout<<get_lcp(sa[i-1],sa[i])<<' ';
    53    }
    54    cout<<endl;
    55 }

     

     

  • 相关阅读:
    基于bootstrap实现收缩导航条
    js判断打开网站页面是PC端还是手机端
    vs2015调试sqlserver 存储过程
    C#计算当前日是第几周
    C#计算一年有多少周
    tcpdump命令的使用
    keepalived配置
    正则匹配中文
    git merge 和 git rebase详解
    systemd和sysv服务管理和配置
  • 原文地址:https://www.cnblogs.com/hhyx/p/12514886.html
Copyright © 2011-2022 走看看