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

    /*P1860 后缀数组
    时间: 1000ms / 空间: 131072KiB / Java类名: Main
    描述

    我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串。
    后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])<suffix(sa[i+1]) 按照字典序方式比较
    定义height[i]表示suffix(sa[i])与suffix(sa[i-1])之间的最长公共前缀长度,其中height[1]=0
    你的任务就是求出SA和height这两个数组。字符串长度<=200000
    输入格式

    一行,为描述中的字符串(仅会出现小写字母)
    输出格式

    共两行,每行n个数,第一行为sa[i],第二行为height[i],其中每行的数均用空格隔开
    测试样例1

    输入

    aabaaaab
    输出

    4 5 6 1 7 2 8 3
    0 3 2 3 1 2 0 1*/
    //本题算法就是题目名,而且还是后缀数组最简单的应用。
    //关于后缀数组我不想多说,推荐 算法合集之《后缀数组——处理字符串的有力工具》此h非我代码中的h。
    //有时真想有人给我讲讲,自学是非常非常痛苦的。
    //但有2个点超时,不过不管了。
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 200008
    using namespace std;
    int n,sa[2][N],rk[2][N],a[N],v[N],k,h[N];
    char ch[N];
    void geng(int sa[N],int rk[N],int SA[N],int RK[N])
    {
    for(int i=1;i<=n;i++)
    v[rk[sa[i]]]=i;
    for(int i=n;i;i--)
    if(sa[i]>k)
    SA[v[rk[sa[i]-k]]--]=sa[i]-k;
    for(int i=n-k+1;i<=n;i++)
    SA[v[rk[i]]--]=i;
    for(int i=1;i<=n;i++)
    RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+k]!=rk[SA[i-1]+k]);
    return;
    }
    int main()
    {
    gets(ch+1);
    n=strlen(ch+1);
    for(int i=1;i<=n;i++)
    a[i]=ch[i]-'a'+1;
    int p=0,q=1;
    for(int i=1;i<=n;i++)
    v[a[i]]++;
    for(int i=2;i<27;i++)
    v[i]+=v[i-1];
    for(int i=1;i<=n;i++)
    sa[p][v[a[i]]--]=i;
    for(int i=1;i<=n;i++)
    rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
    for(k=1;k<n;k<<=1)
    {
    geng(sa[p],rk[p],sa[q],rk[q]);
    swap(p,q);
    }
    for(int i=1;i<=n;i++)
    printf("%d ",sa[p][i]);
    printf(" ");
    k=0;
    for(int i=1;i<=n;i++)
    if(rk[p][i]==1)
    h[1]=0;
    else
    {
    int j=sa[p][rk[p][i]-1];
    for(;a[i+k]==a[j+k];k++);
    h[rk[p][i]]=k;
    if(k>0)
    k--;
    }
    for(int i=1;i<=n;i++)
    printf("%d ",h[i]);
    return 0;
    }

  • 相关阅读:
    【转】Android之四大组件、六大布局、五大存储
    Android O 8.0 奥利奥
    安卓7.1新特性
    那些年我们踩过的坑,SQL 中的空值陷阱!
    8年经验面试官详解 Java 面试秘诀
    Github 第三方授权登录教程
    40个超有趣的Linux命令行彩蛋和游戏
    Synchronized锁在Spring事务管理下,为啥还线程不安全?
    Windows Server 2008 R2文件服务器升级到Windows Server 2016
    牛客练习赛61
  • 原文地址:https://www.cnblogs.com/xydddd/p/5150532.html
Copyright © 2011-2022 走看看