Description

求两个串的最长连续公共字串

Solution

后缀数组入门题吧

把两个串连在一起,中间加一个分隔符,然后跑一遍后缀数组,得到 height 和 sa

一个 height[i] 对答案有贡献的充要条件是 sa[i] 和 sa[i-1] 分别在两个串中

Code

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstdio>
  4. #include <cstring>
  5. using namespace std;
  6. const int N = 200200;
  7. char s1[N], s2[N], S[N];
  8. int n, tmpn, cnt[N], ans, sa[N], rk[N], height[N];
  9. struct node { int id, x, y; } a[N], b[N];
  10. int main() {
  11. scanf("%s %s", s1, s2); tmpn = strlen(s1);
  12. for(int i = 0; s1[i]; i++) S[++n] = s1[i]; S[++n] = '#';
  13. for(int i = 0; s2[i]; i++) S[++n] = s2[i];
  14. for(int i = 1; i <= n; i++) cnt[S[i]] = 1;
  15. for(int i = 0; i <= 128; i++) cnt[i] += cnt[i - 1];
  16. for(int i = 1; i <= n; i++) rk[i] = cnt[S[i]];
  17. for(int L = 1; L <= n; L *= 2) {
  18. for(int i = 1; i <= n; i++)
  19. a[i].id = i, a[i].x = rk[i], a[i].y = rk[i + L];
  20. for(int i = 1; i <= n; i++) cnt[i] = 0;
  21. for(int i = 1; i <= n; i++) cnt[a[i].y]++;
  22. for(int i = 1; i <= n; i++) cnt[i] += cnt[i - 1];
  23. for(int i = 1; i <= n; i++) b[cnt[a[i].y]--] = a[i];
  24. for(int i = 1; i <= n; i++) cnt[i] = 0;
  25. for(int i = 1; i <= n; i++) cnt[a[i].x]++;
  26. for(int i = 1; i <= n; i++) cnt[i] += cnt[i - 1];
  27. for(int i = n; i >= 1; i--) a[cnt[b[i].x]--] = b[i];
  28. for(int i = 1; i <= n; i++)
  29. if(a[i].x == a[i - 1].x && a[i].y == a[i - 1].y)
  30. rk[a[i].id] = rk[a[i - 1].id];
  31. else rk[a[i].id] = rk[a[i - 1].id] + 1;
  32. } for(int i = 1; i <= n; i++) sa[rk[i]] = i;
  33. int k = 0;
  34. for(int i = 1; i <= n; i++) {
  35. int j = sa[rk[i] - 1]; if(k) k--;
  36. while(i + k <= n && j + k <= n && S[i + k] == S[j + k]) k++;
  37. height[rk[i]] = k;
  38. } for(int i = 1; i <= n; i++)
  39. if(sa[i] <= tmpn && sa[i - 1] > tmpn ||
  40. sa[i] > tmpn && sa[i - 1] <= tmpn)
  41. ans = max(ans, height[i]);
  42. printf("%d\n", ans);
  43. return 0;
  44. }

题解【poj2774 Long Long Message】的更多相关文章

  1. POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串

    题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072 ...

  2. POJ2774 Long Long Message 【SAM】

    POJ2774 Long Long Message 找两个串的最长公共字串 对其中一个串\(s\)建\(SAM\),然后我们如何找到最长公共字串,办法就是枚举\(t\)串所有的前缀,然后找各个前缀的最 ...

  3. [POJ2774]Long Long Message 解题报告

    Long Long Message Description The little cat is majoring in physics in the capital of Byterland. A p ...

  4. POJ2774 Long Long Message [后缀数组]

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 29277   Accepted: 11 ...

  5. poj2774 Long Long Message(后缀数组or后缀自动机)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Long Long Message Time Limit: 4000MS   Me ...

  6. 题解 CF950B 【Intercepted Message】

    题目链接 先吐槽一番:本宝宝好久没写过题解了...首先我们想一个贪心策咯.就是我们预处理出前缀和,然后一边扫过去,记录一个l1,l2和一个n1,n2.分别表示我们现在第一个数组切到l1,上一次切是在n ...

  7. poj2774 Long Long Message(后缀数组)

    [题目链接] http://poj.org/problem?id=2774 [题意] A & B的最长公共子序列. [思路] 拼接+height数组.将AB拼接成一个形如A$B的串,枚举hei ...

  8. poj2774 Long Long Message 后缀数组求最长公共子串

    题目链接:http://poj.org/problem?id=2774 这是一道很好的后缀数组的入门题目 题意:给你两个字符串,然后求这两个的字符串的最长连续的公共子串 一般用后缀数组解决的两个字符串 ...

  9. [POJ2774]Long Long Message

    vjudge 一句话题意 给两个串,求最长公共子串. sol 把两个串接在一起求后缀数组.其实中间最好用一个没有出现过的字符连接起来. 判断如果\(SA[i]\)和\(SA[i-1]\)不属于同一个串 ...

随机推荐

  1. OpenMPI源码剖析1:MPI_Init初探

    OpenMPI的底层实现: 我们知道,OpenMPI应用起来还是比较简单的,但是如果让我自己来实现一个MPI的并行计算,你会怎么设计呢?————这就涉及到比较底层的东西了. 回想起我们最简单的代码,通 ...

  2. CPU设计学习-流水线

    各种名词 标量流水线 超级流水线 超标量流水线与多发射技术 经典五级流水线 IF |Instruction Fetch,取指 ID |Instruction Decode,译码 EX |Execute ...

  3. Ubuntu—终端下重启与关机

    重启命令 :         1.shutdown -r now 立刻重启    2.shutdown -r 10 过10分钟自动重启    3.shutdown -r 20:35 在时间为20:35 ...

  4. 57[LeetCode] Insert Interval

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...

  5. LeetCode 144 ——二叉树的前序遍历

    1. 题目 2. 解答 2.1. 递归法 定义一个存放树中数据的向量 data,从根节点开始,如果节点不为空,那么 将当前节点的数值加入到 data 中 递归得到其左子树的数据向量 temp,将 te ...

  6. Python3 小工具-TCP半连接扫描

    from scapy.all import * import optparse import threading def scan(ip,port): pkt=IP(dst=ip)/TCP(dport ...

  7. Java程序员自我介绍

    有关Java程序员的面试自我介绍范文(一) 我叫XXX,今年21岁,毕业于XX解放军信息工程大学计算机科学与技术专业,拥有扎实的Core Java基础,良好的编程风格;熟悉JSP+Servlet+Ja ...

  8. 使用Response.Write实现在页面的生命周期中前后台的交互

    Response.Write()方法非常的常见,也很普通,就是向http output中输出一string.其输出的内容位于页面的最顶端,常用来实现显示一些页面消息框等逻辑. 一般来说,在页面的整个生 ...

  9. 2018-9-25kanboard安装及使用

    2018-9-25kanboard安装及使用 教程 小书匠  欢迎走进zozo的学习之旅. 简介 运行官方docker容器 使用kanboard 简介 Kanboard的安装提供了两种方式一种是直接安 ...

  10. 数组的引用——用作形参&返回类型时

    一.数组的引用 切入:可以将一个变量定义成数组的引用(这个变量和数组的类型要相同) 形式: int odd[5] = {1, 3, 5, 7, 9}; int (&arr)[5] = odd; ...