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

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

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

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <numeric>
#include <cassert> using namespace std; const int N=;; char s[N]; struct SuffixArray {
int wa[N], wb[N], cnt[N], wv[N];
int rk[N], height[N];
int sa[N];
bool cmp(int r[], int a, int b, int l) {
return r[a] == r[b] && r[a+l] == r[b+l];
}
void calcSA(char r[], int n, int m) {
int i, j, p, *x = wa, *y = wb;
for (i = ; i < m; ++i) cnt[i] = ;
for (i = ; i < n; ++i) cnt[x[i]=r[i]]++;
for (i = ; i < m; ++i) cnt[i] += cnt[i-];
for (i = n-; i >= ; --i) sa[--cnt[x[i]]] = i;
for (j = , p = ; p < n; j *= , m = p) {
for (p = , i = n - j; i < n; ++i) y[p++] = i;
for (i = ; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
for (i = ; i < n; ++i) wv[i] = x[y[i]];
for (i = ; i < m; ++i) cnt[i] = ;
for (i = ; i < n; ++i) cnt[wv[i]]++;
for (i = ; i < m; ++i) cnt[i] += cnt[i-];
for (i = n-; i >= ; --i) sa[--cnt[wv[i]]] = y[i];
for (swap(x, y), p = , x[sa[]] = , i = ; i < n; ++i)
x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p- : p++;
}
}
void calcHeight(char r[], int n) {
int i, j, k = ;
for (i = ; i <= n; ++i) rk[sa[i]] = i;
for (i = ; i < n; height[rk[i++]] = k)
for (k?k--:, j = sa[rk[i]-]; r[i+k] == r[j+k]; k++);
}
bool solve(int k,int n,int div) {
int ca=,cb=;
for (int i=;i<=n;i++) {
if (height[i]<k) {
if (ca==&&cb==)
return true;
ca=;cb=;
if (sa[i]<div) ca++;
else if (sa[i]>div) cb++;
continue;
}
if (sa[i]<div) ca++;
else if (sa[i]>div) cb++;
}
return ca==&&cb==;
}
}suf; char a[N],b[N]; int main(){
scanf("%s %s",a,b);
int n=strlen(a),m=strlen(b);
strcpy(s,a);
s[n]='#';
strcpy(s+n+,b);
int tot=n+m+;
suf.calcSA(s,tot+,);
suf.calcHeight(s,tot);
int ret=-;
for (int i=;i<=n;i++) {
if (suf.solve(i,tot,n)) {
ret=i;
break;
}
}
printf("%d\n",ret);
return ;
}

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. oracle目录操作

    1.创建目录 create directory dir_name as 'dir_path'  (dir_path必须事先手动创建) 2.授权 grant read,write on director ...

  2. KoaHub.JS基于Node.js开发的mysql的node.js驱动程序代码

    mysql A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 10 ...

  3. KoaHub.js可借助 Babel 编译稳定运行在 Node.js 环境上

    koahubjs KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Function, Class, A ...

  4. win10如何合并硬盘分区

    好多人都会讲电脑硬盘分成几个不同的区,以方便自己的资料的存储和查找,但不少人不知道如何合并已经分出的硬盘分区.以下是我的经验,与大家分享: 1.   首先,右击“此电脑”,在弹出来的右键菜单这种选择“ ...

  5. 关于使用lazytag的线段树两种查询方式的比较研究

    说到线段树,想来大家并不陌生——最基本的思路就是将其规划成块,然后只要每次修改时维护一下即可. 但是尤其是涉及到区间修改时,lazytag的使用往往能够对于程序的质量起到决定性作用(Ex:一般JSOI ...

  6. poolingHttpclientConnectionmanager 使用

    在阅读 netflix zuul 的simpleHostRoutingFilter 中,发现了一些问题. 主要是关于poolingHttpclientConnectionmanager. 在寻找其中的 ...

  7. intellij idea打jar包时的注意事项

    intellij idea项目在打包maven项目时,数据路径很容易出现问题.在IDE内直接运行不会报错,但打成jar包运行就会报错. intellij打包的几种方式:http://www.cnblo ...

  8. [复习]java中hashCode的作用

    1.HashCode的官方文档定义 (1)hashcode方法返回该对象的哈希码值.支持该方法是为哈希表提供一些优点,例如java.util.HashTable提供的哈希表. (2)hashCode的 ...

  9. iOS 应用关于弥补安全优化问题

    1.log输出会被中奖者截获,暴露信息,影响app得性能 在工程里面的pch文件加入以下代码 // 调试状态 #define LMLog(...) NSLog(__VA_ARGS__) #else / ...

  10. Linux线程的创建

    一.线程与进程的区别 1.线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源. 2.进程是资源分配的基本单位.所有与该进程有关的资源,都 ...