codevs3160 最长公共子串
传送门:http://codevs.cn/problem/3160/
【题解】
CTSC前复习模板
sa的模板。。记住基数排序就够了(还有height)
还有就是sa[i]表示排名为i的后缀是啥。。rnk[i]表示suf(i)排第几
至于其他。。看造化了
大多数关于两个串的都要把它们接起来,然后上SA。
(两个串瞎jb匹配明明还可以FFT嘛)
那么这题。。按套路就是这么走的
可是怎么计算贡献呢
我们发现这样一个事情:
如果suf(sa[i]),suf(sa[j])有公共部分,那么一定不比suf(sa[i],suf(sa[j+1])劣。
我们按照后缀排序后,如果sa[i],sa[i+1]一个处于前半(s1),一个处于后半(s2),那么就是一个合法的匹配,更新答案。
另:还是不会SAM
# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 2e5 + ;
const int mod = 1e9+; # define RG register
# define ST static char s1[M], s2[M];
char str[M];
int n, len1, len2; namespace SA {
// rnk[i]: i后缀排名多少;sa[i]: 排名为i的后缀是哪个
int rnk[M], sa[M], h[M], tsa[M], A[M], B[M];
int cntA[M], cntB[M];
inline void set() {
memset(cntA, , sizeof cntA);
for (int i=; i<=n; ++i) ++cntA[str[i]];
for (int i=; i<=; ++i) cntA[i] += cntA[i-];
for (int i=n; i; --i) sa[cntA[str[i]] --] = i;
rnk[sa[]] = ;
for (int i=; i<=n; ++i) {
rnk[sa[i]] = rnk[sa[i-]];
if(str[sa[i]] != str[sa[i-]]) ++rnk[sa[i]];
}
for (int len=; rnk[sa[n]] < n; len<<=) {
memset(cntA, , sizeof cntA);
memset(cntB, , sizeof cntB);
for (int i=; i<=n; ++i) {
cntA[A[i] = rnk[i]] ++;
cntB[B[i] = ((i + len <= n) ? rnk[i+len] : )] ++;
}
for (int i=; i<=n; ++i) cntA[i] += cntA[i-], cntB[i] += cntB[i-];
for (int i=n; i; --i) tsa[cntB[B[i]] --] = i;
for (int i=n; i; --i) sa[cntA[A[tsa[i]]] --] = tsa[i];
rnk[sa[]] = ;
for (int i=; i<=n; ++i) {
rnk[sa[i]] = rnk[sa[i-]];
if(A[sa[i]] != A[sa[i-]] || B[sa[i]] != B[sa[i-]]) ++rnk[sa[i]];
}
}
for (int i=, j=; i<=n; ++i) {
if(j) --j;
while(str[i+j] == str[sa[rnk[i]-]+j]) ++j;
h[rnk[i]] = j;
}
}
} int main() {
scanf("%s", s1);
len1 = strlen(s1);
for (int i=; i<len1; ++i) str[++n] = s1[i];
str[++n] = ;
scanf("%s", s2);
len2 = strlen(s2);
for (int i=; i<len2; ++i) str[++n] = s2[i];
SA::set();
int bet = len1 + , ans = ;
for (int i=; i<n; ++i) {
if((SA::sa[i] < bet && SA::sa[i+] > bet) || (SA::sa[i] > bet && SA::sa[i+] < bet))
ans = max(ans, SA::h[i+]);
}
printf("%d\n", ans);
return ;
}
codevs3160 最长公共子串的更多相关文章
- [codevs3160]最长公共子串解题报告|后缀自动机
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这 ...
- 【codevs3160】最长公共子串 后缀数组
题目描述 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入 读入两个字符串 输出 输出最长公共子串的长度 样例输入 yeshowmuchiloveyoumydearmotherrea ...
- 【spoj2774】最长公共子串
题目描述: 给你两个字符串,求它们最长公共子串的长度,如果不存在公共子串则输出0. 样例输入: yeshowmuchiloveyoumydearmotherreallyicannotbelieveit ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
- HDU 1503 带回朔路径的最长公共子串
http://acm.hdu.edu.cn/showproblem.php?pid=1503 这道题又WA了好几次 在裸最长公共子串基础上加了回溯功能,就是给三种状态各做一个 不同的标记.dp[n][ ...
- 最长公共子序列PK最长公共子串
1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. (1)递归方法求最长公共子序列的长度 1) ...
- 动态规划(一)——最长公共子序列和最长公共子串
注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...
- 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message
Language: Default Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 21 ...
随机推荐
- python的正则表达一
一.常用的正则表达式 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种 ...
- C#窗口抖动
用过QQ的窗口抖动功能吧.是不是觉得很神奇?很有意思?其实,仔细想想,使用的原理还是挺简单的:让窗口的位置不断快速地发生变化. 说出了原理,是不是一下恍然大悟?顿时理解了.我以前也想过如何实现这个功能 ...
- 【jQuery】 常用函数
[jQuery] 常用函数 html() : 获取设置元素内的 html,包含标签 text() : 获取设置元素内的文本, 不包含标签 val() : 获取设置 value 值 attr() : 获 ...
- Linux上Makefile管理java项目
前面文章讲到了Linux上通过.spec文件与rpmbuild命令将java程序打包为RPM安装包, 现阶段遇到新的需求: 使用Makefile来操纵java的编译.打包 该需求以前面的内容为基础 可 ...
- Vue学习(一):Vue实例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 目标检测之Faster-RCNN的pytorch代码详解(数据预处理篇)
首先贴上代码原作者的github:https://github.com/chenyuntc/simple-faster-rcnn-pytorch(非代码作者,博文只解释代码) 今天看完了simple- ...
- [leetcode-652-Find Duplicate Subtrees]
Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...
- BZOJ 3670 NOI2014 动物园 KMP+dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3670 题意概述:令num[i]表示字符串由1~i的字符形成的前缀中不相重叠的相同前后缀的数 ...
- 有向图的强连通分量——kosaraju算法
一.前人种树 博客:Kosaraju算法解析: 求解图的强连通分量
- [boost-3] 函数对象
boost库学习: 函数对象,成为‘高阶函数’,可以呗传入到其他函数或者从其他函数返回的一类函数. Boost.Bind可替换来自c++标准中的std::bind1st()和std::bind2dn( ...