POJ 3415 Common Substrings 后缀数组
来源:互联网 发布:氮泵 副作用 知乎 编辑:程序博客网 时间:2024/06/05 09:29
题目:
http://poj.org/problem?id=3415
题意:
给定两个字符串,求这两个字符串中长度大于等于k的公共子串的数量
思路:
不得不说,这题我不会,看的别人的,心累。。。看这篇http://www.cnblogs.com/luxiaoming/p/5270984.html
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int N = 200000 + 10, INF = 0x3f3f3f3f;int sa[N], height[N], rnk[N], wa[N], wb[N], c[N];char str[N];int s[N];int stk[N][2];bool cmp(int *r, int a, int b, int l){ return r[a] == r[b] && r[a+l] == r[b+l];}void Rsort(int *x, int *y, int n, int m){ for(int i = 0; i < m; i++) c[i] = 0; for(int i = 0; i < n; i++) c[x[y[i]]]++; for(int i = 1; i < m; i++) c[i] += c[i-1]; for(int i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];}void da(int *s, int n, int m){ int *x = wa, *y = wb; for(int i = 0; i < n; i++) x[i] = s[i], y[i] = i; Rsort(x, y, n, m); for(int j = 1, p = 1; p < n; j *= 2, m = p) { p = 0; for(int i = n-j; i < n; i++) y[p++] = i; for(int i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j; Rsort(x, y, n, m); swap(x, y); p = 1; x[sa[0]] = 0; for(int i = 1; i < n; i++) x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++; }}void get_height(int *s, int n){ int i, j, k = 0; for(i = 0; i <= n; i++) rnk[sa[i]] = i; for(i = 0; i < n; height[rnk[i++]] = k) for(k ? --k : 0, j = sa[rnk[i]-1]; s[i+k] == s[j+k]; k++);}int main(){ int k; while(scanf("%d", &k), k) { scanf("%s", str); int len = 0, len_1 = strlen(str); for(int i = 0; str[i]; i++) s[len++] = str[i]; s[len++] = '$'; scanf("%s", str); for(int i = 0; str[i]; i++) s[len++] = str[i]; s[len] = 0; da(s, len+1, 150); get_height(s, len); ll ans = 0, num = 0; int top = 0; for(int i = 2; i <= len; i++) { if(height[i] < k) top = 0, num = 0; else { int tmp = 0; if(sa[i-1] < len_1) tmp++, num += height[i] - k + 1; while(top > 0 && height[i] <= stk[top-1][0]) { top--; num -= stk[top][1] * (stk[top][0] - height[i]); tmp += stk[top][1]; } stk[top][0] = height[i], stk[top++][1] = tmp; if(sa[i] > len_1) ans += num; } } top = 0, num = 0; for(int i = 2; i <= len; i++) { if(height[i] < k) top = 0, num = 0; else { int tmp = 0; if(sa[i-1] > len_1) tmp++, num += height[i] - k + 1; while(top > 0 && height[i] <= stk[top-1][0]) { top--; num -= stk[top][1] * (stk[top][0] - height[i]); tmp += stk[top][1]; } stk[top][0] = height[i], stk[top++][1] = tmp; if(sa[i] < len_1) ans += num; } }// for(int i = 0; i < len_1; i++)// for(int j = len_1 + 1; j < len; j++)// {// int st = min(rnk[i], rnk[j]), en = max(rnk[i], rnk[j]);// int t = INF;// for(int q = st+1; q <= en; q++) t = min(t, height[q]);//这步可以优化掉,不过无所谓啦。。。// if(t >= k)ans += t - k + 1;// } printf("%lld\n", ans); } return 0;}
阅读全文
0 0
- poj 3415 Common Substrings 后缀数组
- 【后缀数组】 POJ 3415 Common Substrings
- poj 3415 Common Substrings (后缀数组应用)
- [POJ 3415]Common Substrings(后缀数组)
- POJ 3415 Common Substrings 后缀数组
- POJ 3415 Common Substrings(后缀数组:后缀公共前缀个数)
- poj 3415 Common Substrings(后缀数组 | 后缀自动机)
- POJ 3415 Common Substrings(后缀数组+单调栈)
- POJ 3415Common Substrings 后缀数组 + 线段树 + dfs
- POJ 3415 Common Substrings 后缀数组 计数 单调栈优化
- 【POJ】3415 Common Substrings 【后缀数组+单调栈】
- POJ 3415 Common Substrings(后缀数组求重复字串)
- POJ 3415 Common Substrings 后缀数组 + 单调栈维护
- poj 3415 Common Substrings(后缀数组+单调栈)
- POJ 3415:Common Substrings 后缀数组+单调栈
- POJ 3415 Common Substrings(后缀数组+单调栈)
- [POJ 3415] Common Substrings (后缀数组+单调栈优化)
- poj 3415 Common Substrings (后缀数组+单调栈)
- 使用JS实现前端缓存
- HDU 1020 Encoding (String)
- Java动态代理简单理解JDK
- jstl出现问题
- 写时拷贝
- POJ 3415 Common Substrings 后缀数组
- EasyNVR流媒体直播开发时VS2010环境中ffmpeg av_register_all崩溃问题处理
- 设计模式 ----- 设计模式总结
- 5.数据库设计
- 安装Hue后的一些功能的问题解决干货总结
- hadoop学习笔记-HA的配置
- javaee 标准标签库(JSTL)学习总结
- SAS中利用身份证号码求年龄的两种方法
- 6.数据查询(条件