zoukankan      html  css  js  c++  java
  • POJ 2774 Long Long Message 后缀数组模板题

      题意

          给定字符串A、B,求其最长公共子串

      后缀数组模板题,求出height数组,判断sa[i]与sa[i-1]是否分属字符串A、B,统计答案即可。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    const int maxn = 200005;
    char str[maxn];
    int num[maxn];
    int wa[maxn], wb[maxn], wv[maxn], sum[maxn];
    int rank[maxn], sa[maxn], height[maxn];
    
    bool cmp(int *r, int a, int b, int l)
    {
        return (r[a] == r[b]) && (r[a+l] == r[b+l]);
    }
    
    void da(int *r, int *sa, int n, int m)
    {
        int *x = wa, *y = wb, *t;
        for (int i = 1; i <= m; ++i)
            sum[i] = 0;
        for (int i = 1; i <= n; ++i)
            sum[x[i]=r[i]] ++;
        for (int i = 2; i <= m; ++i)
            sum[i] += sum[i-1];
        for (int i = n; i >= 1; --i)
            sa[sum[x[i]]--] = i;
        for (int i, j = 1, p = 1; p < n; j *= 2, m = p)
        {
            for (p = 0, i = n-j+1; i <= n; ++i)
                y[++p] = i;
            for (i = 1; i <= n; ++i)
                if (sa[i]-j >= 1)
                    y[++p] = sa[i]-j;
            for (i = 1; i <= n; ++i)
                wv[i] = x[y[i]];
            for (i = 1; i <= m; ++i)
                sum[i] = 0;
            for (i = 1; i <= n; ++i)
                sum[wv[i]] ++;
            for (i = 2; i <= m; ++i)
                sum[i] += sum[i-1];
            for (i = n; i >= 1; --i)
                sa[sum[wv[i]]--] = y[i];
            for (t = x, x = y, y = t, p = 1, x[sa[1]] = 1, i = 2; i <= n; ++i)
                x[sa[i]] = cmp(y, sa[i], sa[i-1], j) ? p : ++p;
        }/*
        for (int i = 1; i <= n; ++i)
            printf("%d ", sa[i]);
        printf("
    ");*/
    }
    
    void calheight(int *r, int *sa, int n)
    {
        for (int i = 1; i <= n; ++i)
            rank[sa[i]] = i;/*
        for (int i = 1; i <= n; ++i)
            printf("%d ", rank[i]);
        printf("
    ");*/
        int k = 0;
        for (int i = 1; i <= n; ++i)
        {
            if (k > 0)
                k --;
            int j = sa[rank[i]-1];
            while (r[i+k] == r[j+k] && i+k <= n && j+k <= n)
                k ++;
            height[rank[i]] = k;
        }
    }
    
    int main()
    {
        scanf("%s", str);
        int l1 = strlen(str);
        for (int i = 1; i <= l1; ++i)
            num[i] = str[i-1]-'a'+2;
        num[l1+1] = 1;
        scanf("%s", str);
        int l2 = strlen(str);
        for (int i = 1; i <= l2; ++i)
            num[l1+1+i] = str[i-1]-'a'+2;
        da(num, sa, l1+l2+1, 30);
        calheight(num, sa, l1+l2+1);
        int ans = 0;
        for (int i = 3; i <= l1+l2+1; ++i)
            if ((sa[i] <= l1 && sa[i-1] >= l1+2)
             || (sa[i-1] <= l1 && sa[i] >= l1+2))
                ans = max(ans, height[i]);
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    开发Django项目01
    本地安装python2.x和python3.x双版本之后怎么使用pip
    python3.x并发编程
    centos6.8安装JDK1.8教程
    yum安装MySQL指定版本
    python爬虫爬取get请求的页面数据代码样例
    python网络爬虫学习笔记
    python通过get方式,post方式发送http请求和接收http响应-urllib urllib2
    CentOS7.5安装python-pip报Error: Nothing to do解决方法
    文件操作
  • 原文地址:https://www.cnblogs.com/-ZZB-/p/6411277.html
Copyright © 2011-2022 走看看