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

    2.1 最长公共前缀

    height 数组:定义height【i】=suffix(sa【i-1】)和suffix(sa【i】)的最长公共前缀;也就是排名相邻的两个后缀的最长公共前缀。

    那么对于j和k,不妨设rank【j】<rank【k】;不妨设rank【j】<rank【k】,则有以下性质:

    suffix(j)和suffix(k)的最长公共前缀为height【rank【j】+1】到height【rank【k】】中的最小值;

    定义好h【i】=height[rank[i]],也就是suffix(i)和在它前一名的后缀的最长公共前缀;

    h数组有以下性质:

    h【i】》=h【i-1】-1;

    求公共子串

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    #define rep(i,n) for(int i = 0;i < n; i++)
    const int maxn = 200000+66;
    int rk[maxn],sa[maxn],height[maxn],w[maxn],wa[maxn],res[maxn];
    void getSa (int len,int up) {
    int *k = rk,*id = height,*r = res, *cnt = wa;
    rep(i,up) cnt[i] = 0;
    rep(i,len) cnt[k[i] = w[i]]++;
    rep(i,up) cnt[i+1] += cnt[i];
    for(int i = len - 1; i >= 0; i--) {
    sa[--cnt[k[i]]] = i;
    }
    int d = 1,p = 0;
    while(p < len){
    for(int i = len - d; i < len; i++)
    id[p++] = i;
    rep(i,len)
    if(sa[i] >= d)
    id[p++] = sa[i] - d;
    rep(i,len) r[i] = k[id[i]];
    rep(i,up) cnt[i] = 0;
    rep(i,len) cnt[r[i]]++;
    rep(i,up) cnt[i+1] += cnt[i];
    for(int i = len - 1; i >= 0; i--) {
    sa[--cnt[r[i]]] = id[i];
    }
    swap(k,r);
    p = 0;
    k[sa[0]] = p++;
    rep(i,len-1) {
    if(sa[i]+d < len && sa[i+1]+d <len &&r[sa[i]] == r[sa[i+1]]&& r[sa[i]+d] == r[sa[i+1]+d])
    k[sa[i+1]] = p - 1;
    else k[sa[i+1]] = p++;
    }
    if(p >= len) return ;
    d *= 2,up = p, p = 0;
    }
    }
    int ans=0;
    void getHeight(int len) {

    rep(i,len) rk[sa[i]] = i;
    height[0] = 0;
    for(int i = 0,p = 0; i < len - 1; i++) {
    int j = sa[rk[i]-1];
    while(i+p < len&& j+p < len&& w[i+p] == w[j+p]) {
    p++;
    }
    height[rk[i]] = p;
    p = max(0,p - 1);
    }
    }
    int getSuffix(char s[]) {
    int len = strlen(s),up = 0;
    for(int i = 0; i < len; i++) {
    w[i] = s[i];
    up = max(up,w[i]);
    }
    w[len++] = 0;
    getSa(len,up+1);
    getHeight(len);
    return len;
    }


    int main()
    {
    char s1[maxn];
    scanf("%s",s1);
    int t=strlen(s1);
    s1[t]='0';
    scanf("%s",s1+t+1);
    getSuffix(s1);
    int t1=strlen(s1);
    int ans=0;
    for(int i=0;i<t1;i++)
    {
    if(height[i]>ans)
    {
    if((sa[i]<t&&sa[i-1]>t)||(sa[i]>t&&sa[i-1]<t))
    ans=height[i];
    }
    }
    printf("%d",ans);

    return 0;
    }

  • 相关阅读:
    springboo 添加logback日志
    logback配置日志输出
    认知升级:提升理解层次的NLP思维框架
    2019第29周日
    《如何有效社交》晨读笔记
    控制论模型&心流模型&波模型
    数学中常见的思维模型
    分布式服务跟踪系统
    Spring Cloud Sleuth
    微服务调用跟踪
  • 原文地址:https://www.cnblogs.com/2014slx/p/7835620.html
Copyright © 2011-2022 走看看