题目链接:http://codeforces.com/problemset/problem/427/D

大意是寻找两个字符串中最短的公共子串,要求子串在两个串中都是唯一的。

造一个S#T的串,做后缀数组,从小到大枚举子串长度在height数组中扫描,如果某一个组中来自两个串的数量分别为1,就找到了答案。

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <string>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <math.h>
  8. #include <stdlib.h>
  9. #include <queue>
  10. #include <stack>
  11. #include <map>
  12. #include <set>
  13. #include <ctime>
  14. #include <numeric>
  15. #include <cassert>
  16.  
  17. using namespace std;
  18.  
  19. const int N=;;
  20.  
  21. char s[N];
  22.  
  23. struct SuffixArray {
  24. int wa[N], wb[N], cnt[N], wv[N];
  25. int rk[N], height[N];
  26. int sa[N];
  27. bool cmp(int r[], int a, int b, int l) {
  28. return r[a] == r[b] && r[a+l] == r[b+l];
  29. }
  30. void calcSA(char r[], int n, int m) {
  31. int i, j, p, *x = wa, *y = wb;
  32. for (i = ; i < m; ++i) cnt[i] = ;
  33. for (i = ; i < n; ++i) cnt[x[i]=r[i]]++;
  34. for (i = ; i < m; ++i) cnt[i] += cnt[i-];
  35. for (i = n-; i >= ; --i) sa[--cnt[x[i]]] = i;
  36. for (j = , p = ; p < n; j *= , m = p) {
  37. for (p = , i = n - j; i < n; ++i) y[p++] = i;
  38. for (i = ; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
  39. for (i = ; i < n; ++i) wv[i] = x[y[i]];
  40. for (i = ; i < m; ++i) cnt[i] = ;
  41. for (i = ; i < n; ++i) cnt[wv[i]]++;
  42. for (i = ; i < m; ++i) cnt[i] += cnt[i-];
  43. for (i = n-; i >= ; --i) sa[--cnt[wv[i]]] = y[i];
  44. for (swap(x, y), p = , x[sa[]] = , i = ; i < n; ++i)
  45. x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p- : p++;
  46. }
  47. }
  48. void calcHeight(char r[], int n) {
  49. int i, j, k = ;
  50. for (i = ; i <= n; ++i) rk[sa[i]] = i;
  51. for (i = ; i < n; height[rk[i++]] = k)
  52. for (k?k--:, j = sa[rk[i]-]; r[i+k] == r[j+k]; k++);
  53. }
  54. bool solve(int k,int n,int div) {
  55. int ca=,cb=;
  56. for (int i=;i<=n;i++) {
  57. if (height[i]<k) {
  58. if (ca==&&cb==)
  59. return true;
  60. ca=;cb=;
  61. if (sa[i]<div) ca++;
  62. else if (sa[i]>div) cb++;
  63. continue;
  64. }
  65. if (sa[i]<div) ca++;
  66. else if (sa[i]>div) cb++;
  67. }
  68. return ca==&&cb==;
  69. }
  70. }suf;
  71.  
  72. char a[N],b[N];
  73.  
  74. int main(){
  75. scanf("%s %s",a,b);
  76. int n=strlen(a),m=strlen(b);
  77. strcpy(s,a);
  78. s[n]='#';
  79. strcpy(s+n+,b);
  80. int tot=n+m+;
  81. suf.calcSA(s,tot+,);
  82. suf.calcHeight(s,tot);
  83. int ret=-;
  84. for (int i=;i<=n;i++) {
  85. if (suf.solve(i,tot,n)) {
  86. ret=i;
  87. break;
  88. }
  89. }
  90. printf("%d\n",ret);
  91. return ;
  92. }

CF #244 D. Match & Catch 后缀数组的更多相关文章

  1. CF(427D-Match &amp; Catch)后缀数组应用

    题意:给两个字符串,求一个最短的子串.使得这个子串在两个字符串中出现的次数都等于1.出现的定义为:能够重叠的出现. 解法:后缀数组的应用.从小枚举长度.假设一个长度len合法的话:则一定存在这个样的s ...

  2. D. Match & Catch 后缀自动机 || 广义后缀自动机

    http://codeforces.com/contest/427/problem/D 题目是找出两个串的最短公共子串,并且在两个串中出现的次数只能是1次. 正解好像是dp啥的,但是用sam可以方便很 ...

  3. cf244D. Match &amp; Catch 字符串hash (模板)或 后缀数组。。。

    D. Match & Catch 能够用各种方法做.字符串hash.后缀数组,dp.拓展kmp,字典树.. . 字符串hash(模板) http://blog.csdn.net/gdujian ...

  4. codeforces 427D Match & Catch(后缀数组,字符串)

    题目 参考:http://blog.csdn.net/xiefubao/article/details/24934617 题意:给两个字符串,求一个最短的子串.使得这个子串在两个字符串中出现的次数都等 ...

  5. CF 504E Misha and LCP on Tree(树链剖分+后缀数组)

    题目链接:http://codeforces.com/problemset/problem/504/E 题意:给出一棵树,每个结点上有一个字母.每个询问给出两个路径,问这两个路径的串的最长公共前缀. ...

  6. CF 504E Misha and LCP on Tree——后缀数组+树链剖分

    题目:http://codeforces.com/contest/504/problem/E 树链剖分,把重链都接起来,且把每条重链的另一种方向的也都接上,在这个 2*n 的序列上跑后缀数组. 对于询 ...

  7. CF 504 E —— Misha and LCP on Tree —— 树剖+后缀数组

    题目:http://codeforces.com/contest/504/problem/E 快速查询LCP,可以用后缀数组,但树上的字符串不是一个序列: 所以考虑转化成序列—— dfs 序! 普通的 ...

  8. 后缀数组 & 题目

    后缀数组被称为字符串处理神器,要解决字符串问题,一定要掌握它.(我这里的下标全部都是从1开始) 首先后缀数组要处理出两个数组,一个是sa[],sa[i]表示排名第i为的后缀的起始位置是什么,rank[ ...

  9. HDU 5679 Substring 后缀数组判重

    题意:求母串中有多少不同的包含x字符的子串 分析:(首先奉上FZU官方题解) 上面那个题就是SPOJ694 ,其实这两个题一样,原理每次从小到大扫后缀sa数组,加上新的当前后缀的若干前缀,再减去重复的 ...

随机推荐

  1. 学习HTML5一周的收获1

    HTML5的基本结构 学习了title标签(显示网站名称),link标签(链接文件,可做网页美化) 快捷键:Ctrl+/ 注释 学习[meta标签] 1.charset属性:单独使用,设置文档字符集编 ...

  2. UI 事件处理

    一 > 事件的基本概念 事件概述 : UIEvent  ( [ɪ’vent]事件  )  事件,是由硬件捕捉的一个表示用户操作设备的对象 分三类 : 触摸事件 ,晃动事件 ,远程控制事件 触摸事 ...

  3. laravel的延迟消息队列

    laravel的延迟消息队列 这篇来自于看到朋友转的58沈剑的一篇文章:1分钟实现"延迟消息"功能(http://mp.weixin.qq.com/s?__biz=MjM5ODYx ...

  4. cheatsheet——mac 上的一款可以显示软件所有快捷键的小工具

    https://www.mediaatelier.com/CheatSheet/ 发现一款可以显示 mac 上各种软件所有快捷键的小工具:cheatsheet,只要长按 command 键就可以了~ ...

  5. Json 与GeoJson

    1.JSON介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后 ...

  6. mui学习链接

    http://dev.dcloud.net.cn/mui/snippet/ http://www.bcty365.com/content-146-2453-1.html hbuilder转rem值: ...

  7. ubuntu nsight上链接OpenGL

    写一个需要使用OpenGL的程序,右击该程序名,此处需要OpenGL库的程序为Julia-C 右击,选择属性,弹出属性对话框,在左边选择build下的设置,中间窗格中选择GCC C++ Linker下 ...

  8. 5种方法推导Normal Equation

    引言: Normal Equation 是最基础的最小二乘方法.在Andrew Ng的课程中给出了矩阵推到形式,本文将重点提供几种推导方式以便于全方位帮助Machine Learning用户学习. N ...

  9. xgboost-python参数深入理解

    由于在工作中应用到xgboost做特征训练预测,因此需要深入理解xgboost训练过程中的参数的意思和影响. 通过search,https://www.analyticsvidhya.com/blog ...

  10. iOS开发之使程序在后台运行

    方法一(此方法不太可靠): 开启程序后台运行: [application beginBackgroundTaskWithExpirationHandler:^{ //后台运行过期后会调用此block内 ...