【bzoj3796】Mushroom追妹纸 Kmp+二分+Hash
题目描述
输入
输出
样例输入
abcdef
abcf
bc
样例输出
2
题解
Kmp+二分+Hash
先使用Kmp处理出s3在s1、s2中出现的所有位置,那么w的选择不能包含这些位置。
然后答案显然满足二分性质,因此二分答案,判断是否有s1和s2的公共长度为mid的子串。
将s1的所有长度为mid且不包含s3的子串的Hash值处理出来,放到哈希表中,然后将s2的所有长度为mid且不包含s3的子串的Hash值放到哈希表里查询即可。
其中判断是否包含s3的子串可以使用前缀后缀和:对于当前的[l,r],如果不合法,相当于在r前面出现过的右端点加上l后面出现过的左端点大于总数目。
Hash的过程可以直接使用自然溢出。
时间复杂度 $O(n\log n)$
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #define N 50010
- #define M 30000000
- using namespace std;
- typedef unsigned long long ull;
- ull base[N];
- int n[3] , next[N] , sa[2][N] , sb[2][N];
- char s[3][N];
- struct data
- {
- int head[M] , next[N] , tot;
- ull v[N];
- data() {tot = 0;}
- inline void insert(ull x)
- {
- if(!head[x % M]) head[x % M] = ++tot;
- else
- {
- int i;
- for(i = head[x % M] ; next[i] ; i = next[i]);
- next[i] = ++tot;
- }
- v[tot] = x;
- }
- inline bool count(ull x)
- {
- int i;
- for(i = head[x % M] ; i ; i = next[i])
- if(v[i] == x)
- return 1;
- return 0;
- }
- inline void clear()
- {
- int i;
- for(i = 1 ; i <= tot ; i ++ ) v[i] = next[i] = head[v[i] % M] = 0;
- tot = 0;
- }
- }mp;
- void kmp(int p)
- {
- int i , j;
- for(i = j = 0 ; i < n[p] ; i ++ )
- {
- base[i + 1] = base[i] * 233;
- while(~j && s[p][i] != s[2][j]) j = next[j];
- if(++j == n[2]) sa[p][i - j + 1] ++ , sb[p][i] ++ , j = next[j];
- }
- for(i = n[p] - 2 ; ~i ; i -- ) sa[p][i] += sa[p][i + 1];
- for(i = 1 ; i < n[p] ; i ++ ) sb[p][i] += sb[p][i - 1];
- }
- bool judge(int mid)
- {
- int i;
- ull v = 0;
- mp.clear();
- for(i = 0 ; i < mid - 1 ; i ++ ) v = v * 233 + s[0][i];
- for(i = mid - 1 ; i < n[0] ; i ++ )
- {
- v = v * 233 + s[0][i];
- if(sa[0][i - mid + 1] + sb[0][i] <= sa[0][0]) mp.insert(v);
- v -= s[0][i - mid + 1] * base[mid - 1];
- }
- v = 0;
- for(i = 0 ; i < mid - 1 ; i ++ ) v = v * 233 + s[1][i];
- for(i = mid - 1 ; i < n[1] ; i ++ )
- {
- v = v * 233 + s[1][i];
- if(sa[1][i - mid + 1] + sb[1][i] <= sa[1][0] && mp.count(v)) return 1;
- v -= s[1][i - mid + 1] * base[mid - 1];
- }
- return 0;
- }
- int main()
- {
- int i , j , l , r , mid , ans = 0;
- for(i = 0 ; i < 3 ; i ++ ) scanf("%s" , s[i]) , n[i] = strlen(s[i]);
- next[0] = -1;
- for(i = 1 , j = -1 ; i <= n[2] ; i ++ )
- {
- while(~j && s[2][j] != s[2][i - 1]) j = next[j];
- next[i] = ++j;
- }
- base[0] = 1 , kmp(0) , kmp(1);
- l = 1 , r = min(n[0] , n[1]);
- while(l <= r)
- {
- mid = (l + r) >> 1;
- if(judge(mid)) ans = mid , l = mid + 1;
- else r = mid - 1;
- }
- printf("%d\n" , ans);
- return 0;
- }
【bzoj3796】Mushroom追妹纸 Kmp+二分+Hash的更多相关文章
- BZOJ3796 Mushroom追妹纸(二分答案+后缀数组+KMP)
求出一个串使得这个串是\(s1,s2\)的子串.串中不包含\(s3\). 如果没有这个\(s3\)就可以二分答案,然后height小于二分值分一组.看看每组里是不是出现过\(s1,s2\)的后缀.判断 ...
- BZOJ3796 Mushroom追妹纸 字符串 SA KMP
原文链接https://www.cnblogs.com/zhouzhendong/p/9253173.html 题目传送门 - BZOJ3796 题意 找一个串 $w$ 满足: 1.$w$ 是 $s_ ...
- [BZOJ3796]Mushroom追妹纸:后缀自动机+KMP
分析 这道题有个\(O(n)\)的后缀自动机做法,感觉很好理解就在这说一下. 先对\(s1\)和\(s2\)求最长公共子串,对于\(s2\)的每一个下标\(i\),求一个\(f[i]\)表示以\(s2 ...
- BZOJ3796 : Mushroom追妹纸
将S1与S2用#号拼接在一起形成S串 将S3与S串跑KMP求出S3在S串中每次出现的位置l[i] 对于S串每个后缀i,求出f[i]表示该串不包含S3串的最长前缀 然后求出S串的后缀数组 先从小到大扫描 ...
- bzoj 3796: Mushroom追妹纸【二分+后缀数组+st表】
把三个串加上ASCII大于z的分隔符连起来,然后求SA 显然每个相同子串都是一个后缀的前缀,所以枚举s1的每个后缀的最长和s2相同的前缀串(直接在排序后的数组里挨个找,最近的两个分别属于s1和s2的后 ...
- 【BZOJ3796】Mushroom追妹纸 二分+hash
[BZOJ3796]Mushroom追妹纸 Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决 ...
- [BZOJ 3796]Mushroom追妹纸
[BZOJ 3796]Mushroom追妹纸 题目 Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他 ...
- 【bzoj3796】Mushroom追妹纸 hash/sa+kmp+二分
Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意--写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他从网上找到了两篇极佳的情书, ...
- 【bzoj3796】Mushroom追妹纸
Portal -->bzoj3796 Description 给出字符串s1.s2.s3,找出一个字符串w,满足: 1.w是s1的子串: 2.w是s2的子串: 3.s3不是w的子串. 求w的 ...
随机推荐
- 20155323刘威良第二次实验 Java面向对象程序设计
20155323刘威良第二次实验 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 ...
- tkinter菜单图标,工具栏
所用的图片: import tkinter as tk from tkinter import messagebox, filedialog, simpledialog, colorchooser f ...
- Centos7使用yum安装MySQL5.6的正确姿势
centos自带的repo是不会自动更新每个软件的最新版本,所以无法通过yum方式安装MySQL的高级版本. 所以,即使使劲用yum -y install mysql mysql-server mys ...
- 初始CSS模板
/*开始 初始CSS模板 开始*/ body, div, address, blockquote, iframe, ul, ol, dl, dt, dd, li, dl, h1, h2, h3, h4 ...
- 初探C#
初探.NET底层原理 学习C#离不开.net平台,因为微软的开发平台真的是太强大了,它为每一个开发者都做了太多太多,但是我们不仅要知道怎么用,而且也应该知道其中的内部到底包含了什么.本篇文章不仅讲一些 ...
- GitHub 多人协作开发 三种方式:
GitHub 多人协作开发 三种方式: 一.Fork 方式 网上介绍比较多的方式(比较大型的开源项目,比如cocos2d-x) 开发者 fork 自己生成一个独立的分支,跟主分支完全独立,pull代码 ...
- Google Chrome插件分享
前言 浏览器是大家日常使用最多的工具之一,对于程序员来说,Google Chrome浏览器当然是大家优选的最爱之一.面对Chrome丰富的插件真的是爱不释手,如何把自己的Chrome调教成自己心仪的样 ...
- 【TCP_协议_socket接口】-jmeter
1.ip 2.端口号 3.传入参数 4.告诉软件返回 最后以为是什么,不然就会报错 或者无限制的等待 查ascll 码表 启动接口的方法
- HPUX 配置zabbix开机自动启动
1. 在/etc/rc.config.d目录下创建zabbixd文件,并增加以下内容: #!/sbin/sh # v1.0 ?zabbixd startup/kill config ...
- HTML5+Bootstrap 学习笔记 4
HTML5 <map> <area> 标签 <map> 标签定义客户端的图像映射.图像映射是带有可点击区域的图像. <area> 标签定义图像映射内部的 ...