zoukankan      html  css  js  c++  java
  • [HDU1403]Longest Common Substring(后缀数组)

    传送门

    求两个串的公共子串(注意,这个公共子串是连续的一段)

    把两个串连在一起,中间再加上一个原字符串中不存在的字符,避免过度匹配。

    求一遍height,再从height中找满足条件的最大值即可。

    为什么只需要相邻两字典序的后缀呢?因为字典序相邻公共前缀一定最大。

    ——代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #define N 200005
     5 #define max(x, y) ((x) > (y) ? (x) : (y))
     6 
     7 int len, n, ans, m = 'z' + 1;
     8 int buc[N], x[N], y[N], sa[N], rank[N], height[N];
     9 char s[N];
    10 
    11 inline void build_sa()
    12 {
    13     int i, k, p;
    14     for(i = 0; i < m; i++) buc[i] = 0;
    15     for(i = 0; i < len; i++) buc[x[i] = s[i]]++;
    16     for(i = 1; i < m; i++) buc[i] += buc[i - 1];
    17     for(i = len - 1; i >= 0; i--) sa[--buc[x[i]]] = i;
    18     for(k = 1; k <= len; k <<= 1)
    19     {
    20         p = 0;
    21         for(i = len - 1; i >= len - k; i--) y[p++] = i;
    22         for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
    23         for(i = 0; i < m; i++) buc[i] = 0;
    24         for(i = 0; i < len; i++) buc[x[y[i]]]++;
    25         for(i = 1; i < m; i++) buc[i] += buc[i - 1];
    26         for(i = len - 1; i >= 0; i--) sa[--buc[x[y[i]]]] = y[i];
    27         std::swap(x, y);
    28         p = 1, x[sa[0]] = 0;
    29         for(i = 1; i < len; i++)
    30             x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
    31         if(p >= len) break;
    32         m = p;
    33     }
    34 }
    35 
    36 inline void build_height()
    37 {
    38     int i, j, k = 0;
    39     for(i = 0; i < len; i++) rank[sa[i]] = i;
    40     for(i = 0; i < len; i++)
    41     {
    42         if(!rank[i]) continue;
    43         if(k) k--;
    44         j = sa[rank[i] - 1];
    45         while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;
    46         height[rank[i]] = k;
    47     }
    48 }
    49 
    50 int main()
    51 {
    52     int i;
    53     while(~scanf("%s", s))
    54     {
    55         n = strlen(s);
    56         s[n] = '#';
    57         scanf("%s", s + n + 1);
    58         len = strlen(s);
    59         build_sa();
    60         build_height();
    61         ans = 0; 
    62         for(i = 1; i < len; i++)
    63             if((sa[i - 1] < n && sa[i] > n) || (sa[i - 1] > n && sa[i] < n))
    64                 ans = max(ans, height[i]);
    65         printf("%d
    ", ans);
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    链表(1) --- 单链表
    .Net性能调优-MemoryPool
    .Net性能调优-WeakReference
    .Net性能调优-ArrayPool
    .Net Core 中的选项Options
    .Net Core配置Configuration源码研究
    .Net中异步任务的取消和监控
    nginx 实现jira反向代理
    k8s-harbor拉取镜像权限问题-imagePullSecrets
    Studio 3T 重置试用日期
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6978820.html
Copyright © 2011-2022 走看看