【字符串哈希+二分】AcWing3508 最长公共子串
题解
首先思考暴力枚举长度为 \(len∈[1, min(strlen(s), strlen(t))]\),最差情况下为字符串 \(s\) 和字符串 \(t\) 全为长度为 \(10000\) 的全英文字符串,时间复杂度: \(O(n^2)\),显然会超时。
容易证明的是:若存在一个长度为 \(x\) 的公共子串,那么一定能在字符串 \(s\) 和字符串 \(t\) 中找到长度为 \(len∈[1, x - 1]\) 的公共子串。
因此,不妨假设最长的公共子串的长度为 \(x\),我们只需要证明不存在长度为 \(x + 1\) 的公共子串即可。该过程枚举长度 \(x\),满足二分性质。
判断字符串 \(s\) 和字符串 \(t\) 是否存在长度为 \(x\) 的公共子串,可以用字符串哈希来达到快速查找。
参考代码
#include<iostream>
#include<vector>
#include<unordered_set>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
using namespace std;
using ull = unsigned long long;
const int N = 10007;
const int P = 131;
ull p[N];
vector<vector<ull>> h1, h2;
string s, t;
int n, m;
bool judge(char &ch) {
return ch >= 'a' && ch <= 'z';
}
void init() {
n = s.size(), m = t.size();
p[0] = 1;
for (int i = 1, j = max(n, m); i <= j; ++ i) p[i] = p[i - 1] * P;
auto func = [&](string& str, vector<vector<ull>>& h, int &len) {
for (int i = 0; i < len; ++ i) {
if (judge(str[i])) {
vector<ull> v = {0ULL};
int j = i;
do {
v.emplace_back(v.back() * P + str[i] - 'a');
++ i;
} while (i < len && judge(str[i]));
h.emplace_back(v);
}
}
};
func(s, h1, n), func(t, h2, m);
}
ull get(vector<ull>& vec, int l, int r) {
return vec[r] - vec[l] * p[r - l];
}
int main() {
IOS
cin >> s >> t;
init();
auto check = [&](int x) -> bool {
unordered_set<ull> ust;
for (auto &h: h1) for (int i = x; i < h.size(); ++ i) ust.insert(get(h, i - x, i));
for (auto &h: h2) {
for (int i = x; i < h.size(); ++ i) {
ull val = get(h, i - x, i);
if (ust.find(val) != ust.end()) return true;
}
}
return false;
};
int le = 0, ri = min(n, m), md;
while (le < ri) {
md = le + ri + 1 >> 1;
if (check(md)) le = md;
else ri = md - 1;
}
cout << le << '\n';
return 0;
}
【字符串哈希+二分】AcWing3508 最长公共子串的更多相关文章
- SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...
- 【codevs3160】最长公共子串 后缀数组
题目描述 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入 读入两个字符串 输出 输出最长公共子串的长度 样例输入 yeshowmuchiloveyoumydearmotherrea ...
- codevs 3160 最长公共子串(SAM)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Ou ...
- POJ-2774-Long Long Message(后缀数组-最长公共子串)
题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...
- codevs 3160 最长公共子串
3160 最长公共子串 http://codevs.cn/problem/3160/ 时间限制: 2 s 空间限制: 128000 KB 题目描述 Description 给出两个由小写字母组 ...
- 【wikioi】3160 最长公共子串(后缀自动机)
http://codevs.cn/problem/3160/ sam的裸题...(之前写了spoj上另一题sam的题目,但是spoj被卡评测现在还没评测完QAQ打算写那题题解时再来详细介绍sam的.. ...
- [codevs3160]最长公共子串解题报告|后缀自动机
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这 ...
- CODE【VS】3160 最长公共子串 (后缀自动机)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...
- CODE【VS】 3160 最长公共子串 (后缀数组)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...
- Codevs 3160 最长公共子串(后缀数组)
3160 最长公共子串 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长 ...
随机推荐
- 你对 Vue.js 的template 编译的理解?
template 是 ES5 新出的语法 ,template 是不会被页面显示的,但是 vue 中会被翻译成 dom 结构 : template 编译的过程 : parse 解析生成ast 抽象语法树 ...
- 一、Spring Boot集成Spring Security专栏
一.Spring Boot集成Spring Security专栏 一.Spring Boot集成Spring Security之自动装配 二.实现功能及软件版本说明 使用Spring Boot集成Sp ...
- 听说过Paas、Saas和Iaas,那你听说过Apaas吗?
互联网行业就喜欢搞一些单词的缩写,在云计算行业,前者有SaaS.PaaS.IaaS,最近两三年APaaS的概念又开始被关注.APaaS到底是什么意思,有什么用,与前三者的区别是什么?本文将对这些问题进 ...
- bresenham算法(贝汉明算法)
- Java 面向对象高级
文章目录 1.静态 1.1 static修饰成员变量 1.2 static修饰成员变量的应用场景 1.3 static修饰成员方法 1.4 工具类 1.5 static的注意事项 1.6 static ...
- mybatis相关-转义字符串报错-Cause: org.xml.sax.SAXParseException
mybatis相关-转义字符串报错-Cause: org.xml.sax.SAXParseException 部分报错信息 Caused by: org.springframework.beans.f ...
- 对比 Unittest 和 Pytest
一.用例编写规则 1,Unittest提供了test cases.test suites.test fixtures.test runner相关的类,让测试更加明确.方便.可控.使用unittest编 ...
- 2024/9/16 CSP-S模拟赛试题
A 这题是很有意思的一个题,思路就是你考虑kt的位置只可能在四个角,因为这种情况下,他的距离才会最远对吧,所以你就暴力找另一个人fengwu的点的位置,然后计算他们之间的距离然后你求一个\(\max\ ...
- Lua代码——使用遗传进化算法(neat算法)玩超级玛丽游戏
前文: 模拟器运行环境及Lua代码--使用遗传进化算法(neat算法)玩超级玛丽游戏 lua语言实现的neat算法代码: -- MarI/O by SethBling -- Feel free to ...
- Nuxt.js 应用中的 schema:extend事件钩子详解
title: Nuxt.js 应用中的 schema:extend事件钩子详解 date: 2024/11/10 updated: 2024/11/10 author: cmdragon excerp ...