POJ3415 Common Substrings
后缀数组 求长度不小于k的公共子串的个数
代码:
#include <stdio.h>
#include <string.h> const int maxn = ;
int len, len1;
int wa[maxn], wb[maxn], wv[maxn], wd[maxn], sa[maxn];
int lcp[maxn], r[maxn], rank[maxn], height[maxn]; int cmp(int *r, int a, int b, int l){
return r[a] == r[b] && r[a+l] == r[b+l];
} void da(int *r, int n, int m){
int i, j, p, *x=wa, *y=wb, *t;
for(i = ; i < m; i++) wd[i] = ;
for(i = ; i < n; i++) wd[x[i] = r[i]]++;
for(i = ; i < m; i++) wd[i] += wd[i-];
for(i = n-; i >= ; i--) sa[--wd[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++) wd[i] = ;
for(i = ; i < n; i++) wd[wv[i]]++;
for(i = ; i < m; i++) wd[i] += wd[i-];
for(i = n-; i >= ; i --) sa[--wd[wv[i]]] = y[i];
for(t = x, x = y, y = t, p = , x[sa[]] = , i = ; i < n; i++){
x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p-: p++;
}
}
} void calHeight(int *r, int n){
int i, j, k = ;
for(i = ; i <= n; i++) rank[sa[i]] = i;
for(i = ; i < n; height[rank[i++]] = k){
for(k ? k-- : , j = sa[rank[i]-]; r[i+k] == r[j+k]; k++);
}
} int main(){
int k;
char str1[maxn], str2[maxn];
while(~scanf("%d", &k)){
if(k==) break;
scanf("%s%s",str1, str2);
len1 = strlen(str1);
len = strlen(str2);
for(int i = ; i < len1; i++){
r[i] = str1[i];
}
r[len1] = '$';
for(int i = ; i < len; i++){
r[i+len1+] = str2[i];
}
len += len1+;
r[len] = ;
da(r, len+, );
calHeight(r, len);
long long res = , sum;
int head, tail;
for(int i = ; i <= len; i++){
if(height[i] < k){
sum = ;
head = tail = maxn;
}
else{
for(int j = head; j < tail; j++){
if(lcp[j] > height[i]){
sum -= lcp[j]-height[i];
lcp[j] = height[i];
}
else break;
}
if(sa[i-] > len1){
lcp[--head] = height[i];
sum += lcp[head]-k+;
}
if(sa[i] < len1) res += sum;
}
}
for(int i = ; i <= len; i++){
if(height[i] < k){
sum = ;
head = tail = maxn;
}
else{
for(int j = head; j < tail; j++){
if(lcp[j] > height[i]){
sum -= lcp[j]-height[i];
lcp[j] = height[i];
}
else break;
}
if(sa[i-] < len1){
lcp[--head] = height[i];
sum += lcp[head]-k+;
}
if(sa[i] > len1) res += sum;
}
}
printf("%I64d\n", res);
}
}
POJ3415 Common Substrings的更多相关文章
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
- POJ3415 Common Substrings(后缀数组 单调栈)
借用罗穗骞论文中的讲解: 计算A 的所有后缀和B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k 的部分全部加起来.先将两个字符串连起来,中间用一个没有出现过的字符隔开.按height ...
- poj3415 Common Substrings(后缀数组,单调栈 | 后缀自动机)
[题目链接] http://poj.org/problem?id=3415 [题意] A与B长度至少为k的公共子串个数. [思路] 基本思想是将AB各个后缀的lcp-k+1的值求和.首先将两个字符串拼 ...
- 2018.12.15 poj3415 Common Substrings(后缀自动机)
传送门 后缀自动机基础题. 给两个字符串,让你求长度不小于kkk的公共子串的数量. 这题可以用后缀自动机解决废话 考虑对其中一个字串建出后缀自动机,然后用另一个在上面跑,注意到如果一个状态有贡献的话, ...
- POJ3415 Common Substrings 【后缀数组 + 单调栈】
常见的子串 时间限制: 5000MS 内存限制: 65536K 提交总数: 11942 接受: 4051 描述 字符串T的子字符串被定义为: Ť(我,ķ)= Ť 我 Ť 我 1 ... Ť I ...
- poj3415 Common Substrings (后缀数组+单调队列)
Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 9414 Accepted: 3123 Description A sub ...
- 【POJ3415】 Common Substrings(后缀数组|SAM)
Common Substrings Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤ ...
- poj 3415 Common Substrings(后缀数组+单调栈)
http://poj.org/problem?id=3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Sub ...
- 字符串(后缀数组):POJ 3415 Common Substrings
Common Substrings Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤ ...
随机推荐
- HDU1070Milk
Milk Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description ...
- uiview 单边圆角或者单边框
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(120, 10, 80, 80)]; view2.backgroundColor = ...
- self._raiseerror(v) File "D:\GameDevelopment\Python27\lib\xml\etree\ElementTree.py", line 1506, in _raiseerror
D:\BaiDuYun\Plist>python unpack_plist.py lobbyRelieveTraceback (most recent call last): File &quo ...
- 收集几个Web前端UI框架
原文:http://www.isaced.com/post-200.html 关于Web前端UI库/框架,我觉得是非常方便的东西,对于我们这种业余的Web开发人员,有时候要写点前端代码的时候把UI框架 ...
- Linux的别名使用
直接定义别名 编辑当前用户下的.bashrc 文件: vim ~/.bashrc 添加别名为 lmysql 的命令语句 : alias lmysql='mysql -uroot -p -Dtest ...
- mysql 中的bool值
boolean在MySQL里的类型为tinyint(1) 很奇怪.
- java 时间戳与日期字符串相互转换
/** * 时间戳转换成日期格式字符串 * @param seconds 精确到秒的字符串 * @param formatStr * @return */ public static String t ...
- android自动化环境搭建
android自动化环境安装指南 1.appium相关安装(eclipse下)见http://www.cnblogs.com/wangcp-2014/p/5717589.html参考selenium的 ...
- Jmeter 快速入门教程(三-3) -- 使用参数化
参数化:简单的来理解一下,我们录制了一个脚本,这个脚本中有登录操作,需要输入用户名和密码,假如系统不允许相同的用户名和密码同时登录,或者想更好的模拟多个用户来登录系统. 这个时候就需要对用户名和密码进 ...
- lintcode:整数排序||
题目 给一组整数,按照升序排序.使用归并排序,快速排序,堆排序或者任何其他 O(n log n) 的排序算法. 解题 归并排序 public class Solution { /** * @param ...