【BZOJ3796】Mushroom追妹纸

Description

Mushroom最近看上了一个漂亮妹纸。他选择一种非常经典的手段来表达自己的心意——写情书。考虑到自己的表达能力,Mushroom决定不手写情书。他从网上找到了两篇极佳的情书,打算选择其中共同的部分。另外,Mushroom还有个一个情敌Ertanis,此人也写了封情书给妹子。
Mushroom不希望自己的情书中完整的出现了情敌的情书。(这样抄袭的事情就暴露了)。
Mushroom把两封情书分别用字符串s1和s2来表示,Ertanis的情书用字符串s3来表示,他要截取的部分用字符串w表示。
需满足:
1、w是s1的子串
2、w是s2的子串
3、s3不是w的子串
4、w的长度应尽可能大
所谓子串是指:在字符串中连续的一段
【输入】
输入文件为girl.in
输入有三行,第一行为一个字符串s1第二行为一个字符串s2, 
第三行为一个字符串s3。输入仅含小写字母,字符中间不含空格。
【输出】
输出文件为girl.out
输出仅有一行,为w的最大可能长度,如w不存在,则输出0。
【输入样例】
abcdef
abcf
bc
【输出样例】
2
【样例解释】
s1和s2的公共子串有abc,ab,bc,a,b,c,f,其中abc,bc包含子串bc不合法,所以最长的合法子串为ab。
【数据规模】
对于30%的数据:1<=s1、s2、s3的长度<=500
对于60%的数据:1<=s1、s2、s3的长度<=5000
对于100%的数据:1<=s1、s2的长度<=50000,1<=s3的长度<=10000

Input

输入有三行,第一行为一个字符串s1第二行为一个字符串s2, 
第三行为一个字符串s3。输入仅含小写字母,字符中间不含空格。

Output

输出仅有一行,为w的最大可能长度,如w不存在,则输出0。

Sample Input

abcdef
abcf
bc

Sample Output

2
【样例解释】
s1和s2的公共子串有abc,ab,bc,a,b,c,f,其中abc,bc包含子串bc不合法,所以最长的合法子串为ab。

HINT

对于100%的数据:1<=s1、s2的长度<=50000,1<=s3的长度<=10000

题解:“没有什么字符串问题是hash解决不了的。”

先用hash找出s3在s1中所有出现的位置,把这些位置都打上危险标记。显然答案是可二分的,于是二分答案。假设当前二分的答案为len,我们将s2中所有长度为len的子串的hash值都拿出来,扔到set里,我们再枚举s1中所有长度为len的子串,如果当前子串再set中出现过,并且当前串中不包含危险标记,则该串是符合要求的。

此外,望大家学习正确的重载运算符的姿势,并养成良好的习惯啊~(当你看见编译时反馈的一大坨信息你就洒sha了。)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
#include <utility>
using namespace std;
const int maxn=50010;
typedef long long ll;
const ll m1=998244353;
const ll m2=1000000007;
struct pll
{
ll F,S;
pll() {}
pll(ll a,ll b){F=a,S=b;}
pll operator * (const ll &b) const {return pll(F*b%m1,S*b%m2);}
pll operator + (const ll &b) const {return pll((F+b)%m1,(S+b)%m2);}
pll operator * (const pll &b) const {return pll(F*b.F%m1,S*b.S%m2);}
pll operator - (const pll &b) const {return pll((F-b.F+m1)%m1,(S-b.S+m2)%m2);}
bool operator < (const pll &b) const {return (F==b.F)?(S<b.S):(F<b.F);}
bool operator == (const pll &b) const {return F==b.F&&S==b.S;}
}h1[maxn],h2[maxn],h3,bs[maxn];
int l1,l2,l3;
char s1[maxn],s2[maxn],s3[maxn];
set<pll> s;
int dan[maxn];
bool solve(int l)
{
int i;
s.clear();
for(i=l;i<=l2;i++) s.insert(h2[i]-(h2[i-l]*bs[l]));
for(i=l;i<=l1;i++)
{
if((l<l3||!(dan[i]-dan[i-l+l3-1]))&&s.find(h1[i]-(h1[i-l]*bs[l]))!=s.end()) return 1;
}
return 0;
}
int main()
{
scanf("%s%s%s",s1,s2,s3),l1=strlen(s1),l2=strlen(s2),l3=strlen(s3);
int i;
for(bs[0]=pll(1,1),i=1;i<=max(l1,l2);i++) bs[i].F=bs[i-1].F*233%m1,bs[i].S=bs[i-1].S*233%m2;
for(i=1;i<=l1;i++) h1[i]=(h1[i-1]*233)+s1[i-1];
for(i=1;i<=l2;i++) h2[i]=(h2[i-1]*233)+s2[i-1];
for(i=1;i<=l3;i++) h3=(h3*233)+s3[i-1];
for(i=l3;i<=l1;i++) if(h1[i]-(h1[i-l3]*bs[l3])==h3) dan[i]=1;
for(i=1;i<=l1;i++) dan[i]+=dan[i-1];
int l=1,r=min(l1,l2)+1,mid;
while(l<r)
{
mid=(l+r)>>1;
if(solve(mid)) l=mid+1;
else r=mid;
}
printf("%d",l-1);
return 0;
}

【BZOJ3796】Mushroom追妹纸 二分+hash的更多相关文章

  1. BZOJ3796 Mushroom追妹纸(二分答案+后缀数组+KMP)

    求出一个串使得这个串是\(s1,s2\)的子串.串中不包含\(s3\). 如果没有这个\(s3\)就可以二分答案,然后height小于二分值分一组.看看每组里是不是出现过\(s1,s2\)的后缀.判断 ...

  2. BZOJ3796 Mushroom追妹纸 字符串 SA KMP

    原文链接https://www.cnblogs.com/zhouzhendong/p/9253173.html 题目传送门 - BZOJ3796 题意 找一个串 $w$ 满足: 1.$w$ 是 $s_ ...

  3. BZOJ3796 : Mushroom追妹纸

    将S1与S2用#号拼接在一起形成S串 将S3与S串跑KMP求出S3在S串中每次出现的位置l[i] 对于S串每个后缀i,求出f[i]表示该串不包含S3串的最长前缀 然后求出S串的后缀数组 先从小到大扫描 ...

  4. [BZOJ3796]Mushroom追妹纸:后缀自动机+KMP

    分析 这道题有个\(O(n)\)的后缀自动机做法,感觉很好理解就在这说一下. 先对\(s1\)和\(s2\)求最长公共子串,对于\(s2\)的每一个下标\(i\),求一个\(f[i]\)表示以\(s2 ...

  5. [BZOJ 3796]Mushroom追妹纸

    [BZOJ 3796]Mushroom追妹纸 题目 Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他 ...

  6. 【bzoj3796】Mushroom追妹纸 hash/sa+kmp+二分

    Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意--写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他从网上找到了两篇极佳的情书, ...

  7. 【bzoj3796】Mushroom追妹纸 Kmp+二分+Hash

    题目描述 给出字符串s1.s2.s3,找出一个字符串w,满足: 1.w是s1的子串: 2.w是s2的子串: 3.s3不是w的子串. 4.w的长度应尽可能大 求w的最大长度. 输入 输入有三行,第一行为 ...

  8. 【bzoj3796】Mushroom追妹纸

    Portal -->bzoj3796 Description 给出字符串s1.s2.s3,找出一个字符串w,满足: 1.w是s1的子串: 2.w是s2的子串: 3.s3不是w的子串. ​ 求w的 ...

  9. BZOJ 3796 Mushroom追妹纸 哈希+二分(+KMP)

    先把两个串能匹配模式串的位置找出来,然后标记为$1$(标记在开头或末尾都行),然后对标记数组求一个前缀和,这样可以快速查到区间内是否有完整的一个模式串. 然后二分子串(答案)的长度,每次把长度为$md ...

随机推荐

  1. PHP中的stristr(),strstr(),strpos()速度比较

    测速代码: <?php function getmicrotime() { list($usec, $sec) = explode(" ",microtime()); ret ...

  2. 记一个react拖动排序中的坑:key

    在做一个基于react的应用的时候遇到了对列表拖动排序的需求.当使用sortable对列表添加排序支持后发现一个问题:数据正确排序了,但是dom的顺序却乱了,找了一会儿原因后发现是因为在渲染数据的时候 ...

  3. Shell 括号辨识(转http://blog.csdn.net/taiyang1987912/article/details/39551385)

    一.小括号,圆括号() 1.单小括号 ()    ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有 ...

  4. Geoserver跨域问题

    1 Geoserver位war包,使用Tomcat发布的情况 由于geoserver为war形式,需要解决tomcat跨域问题,geoserver版本为2.9.1. (1)下载跨域war包 下载cor ...

  5. Rebound动画框架简单介绍

    Rebound动画框架简单介绍 Android菜鸟一枚,有不对的地方希望大家指出,谢谢. 最近在接手了一个老项目,发现里面动画框架用的是facebook中的Rebound框架,由于以前没听说过,放假时 ...

  6. python的依赖性安全性检查

    1.safety 安装: pip install safety 使用: 检查整个系统的依赖包安全性safety check检查某个项目的依赖性安全safety check -r requirement ...

  7. ADO.NET-temple

    ylbtech-ADO.NET:ADO.NET-Oracle|SQLServer|MySql|Access|Excel-dddd 介绍及讲解 1.A,插入数据(Create) 1.B,读取数据(Rea ...

  8. Hadoop部署启动异常问题排查

    hadoop的日志目录(/home/hadoop/app/hadoop-2.6.4/logs) 1.hadoop启动不正常用浏览器访问namenode的50070端口,不正常,需要诊断问题出在哪里: ...

  9. MySQL主从同步异常问题解决Client requested master to start replication from position > file size

    MySQL主从同步异常问题解决Client requested master to start replication from position > file size 一.问题描述 MySQ ...

  10. Unity3D开发基础组件提取总结

    在游戏开发过程中,除了逻辑功能的开发之外,还有非常多基础的模块.这些模块,对大部分手机网络游戏来说都是一样的.所以,在上个游戏已经上线运营大半年之际,我认为有必要将这些模块整理出来.让后面其它游戏的开 ...