题解

首先思考暴力枚举长度为 \(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 最长公共子串的更多相关文章

  1. SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)

    题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...

  2. 【codevs3160】最长公共子串 后缀数组

    题目描述 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入 读入两个字符串 输出 输出最长公共子串的长度 样例输入 yeshowmuchiloveyoumydearmotherrea ...

  3. codevs 3160 最长公共子串(SAM)

    3160 最长公共子串   题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Ou ...

  4. POJ-2774-Long Long Message(后缀数组-最长公共子串)

    题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...

  5. codevs 3160 最长公共子串

    3160 最长公共子串 http://codevs.cn/problem/3160/  时间限制: 2 s  空间限制: 128000 KB   题目描述 Description 给出两个由小写字母组 ...

  6. 【wikioi】3160 最长公共子串(后缀自动机)

    http://codevs.cn/problem/3160/ sam的裸题...(之前写了spoj上另一题sam的题目,但是spoj被卡评测现在还没评测完QAQ打算写那题题解时再来详细介绍sam的.. ...

  7. [codevs3160]最长公共子串解题报告|后缀自动机

    给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这 ...

  8. CODE【VS】3160 最长公共子串 (后缀自动机)

    3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...

  9. CODE【VS】 3160 最长公共子串 (后缀数组)

    3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...

  10. Codevs 3160 最长公共子串(后缀数组)

    3160 最长公共子串 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长 ...

随机推荐

  1. Spring —— 整合JUnit

    整合JUnit   

  2. Spring —— bean生命周期

    bean生命周期 生命周期:从创建到消亡的完整过程 bean生命周期:bean从创建到销毁的整体过程 bean生命周期控制:在bean创建后到销毁前做一些事情   方式一:配置控制生命周期 <b ...

  3. IDEA如何自动导入依赖的jar包

    前言 我们在使用IDEA开发时,会引入第三方的jar包,这些第三方的jar包使我们可以快速的使用别人开发好的功能,而不用重复造轮子了. 这大大提高了我们的开发效率. 但是,有时候我们一下子需要导入太多 ...

  4. 3. 王道OS-操作系统的运行机制,中断和异常

    1. 高级语言- 编译 - 机器指令 (二进制) 2. 内核态和用户态 :刚开机的时候CPU是内核态,当用户启动某个程序的时候CPU是用户态,如果遇到危险,操作系统会夺回CPU的控制权成为内核态,当危 ...

  5. C#查漏补缺----Exception处理实现,无脑抛异常不可取

    前言 环境:.NET 8.0 系统:Windows11 参考资料:CLR via C#, .Net Core底层入门 https://andreabergia.com/blog/2023/05/err ...

  6. 自学PHP笔记(一) PHP语法

    本文转发来自:https://blog.csdn.net/KH_FC/article/details/115407577 PHP基本语法 php使用一对特殊的标记包含php代码,与HTML代码混在一起 ...

  7. att&ack学习笔记4

    初识ATT&CK框架前言:ATT&CK这一概念自2014年提出时起,作为安全分析领域中的前沿研究一直在默默地发挥着自己的影响,但是由于其概念在当时过于超前以至于并没有引起多大反响,直至 ...

  8. cn2 lab 笔记

    Ubuntu 18.04 Kafka 先启动kafka自带的zookeeper 在data/kafka_2.13-3.3.1bin目录下执行 ./zookeeper-server-start.sh . ...

  9. 基于pikachu靶场的水平越权详解

    1. pikachu靶场搭建 如果你在之前已经使用过phpstudy了,参考pikachu 靶场环境搭建 如果在靶场搭建中遇到一些问题,参考皮卡丘靶场搭建遇到的问题大全 2. 水平越权简介 水平越权是 ...

  10. UE4纯C++实现游戏快捷栏之物品读取

    我们在上一步骤中创建了快捷栏的UI界面,在这一部分我们将从Json文件中读取物品的相关信息(种类以及属性),来填充到游戏数据中进行存储以便快捷栏使用,具体分以下几部分完成. 1.Types.h: 添加 ...