CF 427D 后缀数组
2016-03-05 18:17
281 查看
大意是寻找两个字符串中最短的公共子串,要求子串在两个串中都是唯一的。
造一个S#T的串,做后缀数组,从小到大枚举子串长度在height数组中扫描,如果某一个组中来自两个串的数量分别为1,就找到了答案。
View Code
造一个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=10005;; char s ; struct SuffixArray { int wa , wb , cnt , wv ; int rk , height ; int sa ; 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 = 0; i < m; ++i) cnt[i] = 0; for (i = 0; i < n; ++i) cnt[x[i]=r[i]]++; for (i = 1; i < m; ++i) cnt[i] += cnt[i-1]; for (i = n-1; i >= 0; --i) sa[--cnt[x[i]]] = i; for (j = 1, p = 1; p < n; j *= 2, m = p) { for (p = 0, i = n - j; i < n; ++i) y[p++] = i; for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j; for (i = 0; i < n; ++i) wv[i] = x[y[i]]; for (i = 0; i < m; ++i) cnt[i] = 0; for (i = 0; i < n; ++i) cnt[wv[i]]++; for (i = 1; i < m; ++i) cnt[i] += cnt[i-1]; for (i = n-1; i >= 0; --i) sa[--cnt[wv[i]]] = y[i]; for (swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; ++i) x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++; } } void calcHeight(char r[], int n) { int i, j, k = 0; for (i = 0; i <= n; ++i) rk[sa[i]] = i; for (i = 0; i < n; height[rk[i++]] = k) for (k?k--:0, j = sa[rk[i]-1]; r[i+k] == r[j+k]; k++); } bool solve(int k,int n,int div) { int ca=0,cb=0; for (int i=1;i<=n;i++) { if (height[i]<k) { if (ca==1&&cb==1) return true; ca=0;cb=0; 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==1&&cb==1; } }suf; char a ,b ; int main(){ scanf("%s %s",a,b); int n=strlen(a),m=strlen(b); strcpy(s,a); s ='#'; strcpy(s+n+1,b); int tot=n+m+1; suf.calcSA(s,tot+1,128); suf.calcHeight(s,tot); int ret=-1; for (int i=1;i<=n;i++) { if (suf.solve(i,tot,n)) { ret=i; break; } } printf("%d\n",ret); return 0; }
View Code
相关文章推荐
- 39. Combination Sum
- 关于低功耗蓝牙的连接参数更新
- Spring核心IOC容器实现分析
- ViewPager禁止滑动以及它与内层滑动控件水平方向上事件冲突的解决方法
- 深入学习JavaScript的AngularJS框架中指令的使用方法
- 极路由 openwrt 使用 SyncY 实现百度云同步
- 初识Hash
- js
- 反转链表
- Android 实现全屏 去掉标题栏
- spring mvc使用Maven配置Velocity
- 第一次作业
- Java第一周学习总结5311
- 客户端与服务端Post报文构造请求及Http Post与Get请求方法
- IntentService
- JQuery之ajax
- AJAX - 创建 XMLHttpRequest 对象
- JSP九大内置对象和四种属性范围解读
- 编程技巧
- StringBuffer源码分析