题解

首先思考暴力枚举长度为 \(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. Blazor开发框架Known-V2.0.13

    大家好,国庆节快乐,Known又更新了一波功能. 继上个版本以来,一直在完善网站文档.KnownCMS开源项目和解决框架客户提出的一些问题.这期间客户反馈的问题主要如下: 微信模板消息收不到,查其原因 ...

  2. android系统启动流程- ServiceManager进程启动流程

    *注:基于Android11源码 ServiceManager进程是在init进程创建的,所以我们从init进程的main()开始分析: // 文件路径: system/core/init/main. ...

  3. 「模拟赛」A 层多校联训 4(卖品:CTH)

    双倒一啦! 感觉这次最大的错误就是没看 T2.(本质原因还是时间浪费的太多了) 赛时记录在闲话啦 accoder 多校比赛链接 02 表示法 唐诗题!考高精的人都\(**\),输出深度优先搜索解决.高 ...

  4. iOS中委托使用小结

    1.声明委托对象,并根据需要设置方法为可选还是必选,默认设置可选@optional @protocol CCHighSeasPoolDistributeDelegate <NSObject> ...

  5. Oracle问题:alter update modify 的区别是什么?

    首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247486480&idx=1 ...

  6. spring cloud openfeign 源码

    一.读取注解信息 入口 1 import org.springframework.boot.SpringApplication; 2 import org.springframework.boot.a ...

  7. FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件

    ​继音视频播放器ExoPlayer之后,谷歌又推出了音视频转换器Transformer,要在音视频加工领域施展拳脚.根据Android开发者官网介绍:Jetpack Media3是Android媒体库 ...

  8. 图菱科技 SaaS 系统容器化最佳实践

    大家好,我是龚承明,在图菱(成都)科技有限公司任职,主要负责公司的产品系统研发以及公司IT基础设施的建设工作.本篇文章将为大家介绍下我司在采用 KubeSphere 平台实现公司业务系统容器化过程中的 ...

  9. php运行redis测试

    在今天将官方的redis教程看完之后,想自己来一个测试. 按照官方给出的代码: 1 <?php 2 //连接本地的 Redis 服务 3 $redis = new Redis(); 4 $red ...

  10. centos 安装mbstring(mb_strlen )

    部署onethink框架的时候,检测到mb_strlen未支持, 在网上检索一大堆教程,最多的就是先检测一下需要安装的安装包 yum search php 楼主小白满心欢喜地输入,一对照返回的结果, ...