[BZOJ 3796]Mushroom追妹纸
[BZOJ 3796]Mushroom追妹纸
题目
Mushroom最近看上了一个漂亮妹纸。他选择一种非常经典的手段来表达自己的心意——写情书。考虑到自己的表达能力,Mushroom决定不手写情书。他从网上找到了两篇极佳的情书,打算选择其中共同的部分。另外,Mushroom还有个一个情敌Ertanis,此人也写了封情书给妹子。Mushroom不希望自己的情书中完整的出现了情敌的情书。(这样抄袭的事情就暴露了)。Mushroom把两封情书分别用字符串s1和s2来表示,Ertanis的情书用字符串s3来表示,他要截取的部分用字符串w表示。需满足:1、w是s1的子串2、w是s2的子串3、s3不是w的子串4、w的长度应尽可能大所谓子串是指:在字符串中连续的一段INPUT
输入文件为girl.in输入有三行,第一行为一个字符串s1第二行为一个字符串s2,第三行为一个字符串s3。输入仅含小写字母,字符中间不含空格。OUTPUT
输出文件为girl.out输出仅有一行,为w的最大可能长度,如w不存在,则输出0。SAMPLE
INPUT
abcdefabcfbcOUTPUT
2
解题报告
我不会说我一开始看错题废了我一个来小时的= =
首先我们可以把$s1$和$s2$中间加一个不会出现在该字符集中的字符将它俩接在一起,这个字符日常作用是分隔俩字符串
然后,我们对组合得到的字符串与$s3$跑$KMP$处理出每个匹配的串的位置
接下来就是极其简单的最长公共字串问题了,只要在判断时加一个是否被$KMP$标记过的条件即可
一定要读对题啊啊啊
s3不是w的子串!!!
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char ch[][];
int len[],bl[];
char ran[]={'!','@','#','$'};
char s[];
int n,m;
int t1[],t2[],t3[],buc[];
int sa[],rank[],height[];
int kp[];
bool km[];
inline void get_kp(){
kp[]=-;
int i(),j(-);
while(i<len[]){
while(j!=-&&ch[][i]!=ch[][j])
j=kp[j];
kp[++i]=++j;
}
}
inline void kmp(){
int i(),j();
while(i<=n){
while(j!=-&&s[i]!=ch[][j])
j=kp[j];
++i,++j;
if(j==len[])
km[i-len[]]=;
}
}
inline void Suffix(){
int i,j,k(),p(),*x(t1),*y(t2),*t;
for(i=;i<=m;++i)buc[i]=;
for(i=;i<=n;++i)++buc[x[i]=s[i]];
for(i=;i<=m;++i)buc[i]+=buc[i-];
for(i=n;i>=;--i)sa[buc[x[i]]--]=i;
for(j=;p<n;j<<=,m=p){
for(p=,i=n-j+;i<=n;++i)y[++p]=i;
for(i=;i<=n;++i)
if(sa[i]>j)
y[++p]=sa[i]-j;
for(i=;i<=m;++i)buc[i]=;
for(i=;i<=n;++i)t3[i]=x[y[i]];
for(i=;i<=n;++i)++buc[t3[i]];
for(i=;i<=m;++i)buc[i]+=buc[i-];
for(i=n;i>=;--i)sa[buc[t3[i]]--]=y[i];
for(t=x,x=y,y=t,x[sa[]]=,p=,i=;i<=n;++i)
x[sa[i]]=((y[sa[i]]==y[sa[i-]])&&(y[sa[i]+j]==y[sa[i-]+j]))?p:++p;
}
for(i=;i<=n;++i)rank[sa[i]]=i;
for(i=;i<=n;height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-];s[i+k]==s[j+k];++k);
}
inline bool judge(int po,int x){//cout<<l<<' '<<r<<' '<<x<<endl;
if(x<len[])
return true;
for(int i=po,j=;j<=x;++i,++j){
if(km[i]&&j+len[]-<=x)
return false;
}
return true;
}
inline bool check(int x){//cout<<x<<endl;
int i,j,k;
bool flag[];
for(i=;i<=n;++i){//cout<<i<<" "<<height[i]<<endl;
if(height[i]>=x){//cout<<endl;
for(j=i;height[j]>=x&&j<=n;++j);
--j;
// if(i==j)
// continue;
// cout<<i<<" "<<j<<endl<<endl;
memset(flag,,sizeof(flag));
for(k=i-;k<=j;++k)
flag[bl[sa[k]]]=;
if(flag[]&&flag[]&&judge(sa[i-],x))
return true;
// for(k=1;flag[k]&&k<=3;++k);
// if(k==3)
// return true;
i=j;
}
}
return false;
}
int main(){
scanf("%s%s%s",ch[],ch[],ch[]);
for(int i=;i<=;++i)
len[i]=strlen(ch[i]);
for(int i=;i<=;++i){
for(int j=;j<len[i];++j){
s[++n]=ch[i][j];
bl[n]=i;//cout<<n<<' '<<bl[n]<<endl;
}
s[++n]=ran[i];
}
get_kp();
kmp();
m=;
Suffix();
int l(),r(max(len[],len[])),ans();
while(l<=r){
int mid((l+r)>>);
if(check(mid))
ans=mid,l=mid+;
else
r=mid-;
}
printf("%d",ans);
}
[BZOJ 3796]Mushroom追妹纸的更多相关文章
- ●BZOJ 3796 Mushroom追妹纸
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3796 题解: 题意: 给出三个串 A,B,C 找出一个最长串 S, 使得 ...
- bzoj 3796 Mushroom追妹纸——后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3796 长度一般都是 1e5 ,看这个是 5e4 ,一看就是把两个串接起来做. 自己本来想的是 ...
- bzoj 3796 Mushroom追妹纸 —— 后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3796 先把三个串拼在一起,KMP 求 s1 , s2 中每个位置和 s3 的匹配情况: 注意 ...
- bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp
题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...
- BZOJ 3796 Mushroom追妹纸 哈希+二分(+KMP)
先把两个串能匹配模式串的位置找出来,然后标记为$1$(标记在开头或末尾都行),然后对标记数组求一个前缀和,这样可以快速查到区间内是否有完整的一个模式串. 然后二分子串(答案)的长度,每次把长度为$md ...
- bzoj 3796: Mushroom追妹纸【二分+后缀数组+st表】
把三个串加上ASCII大于z的分隔符连起来,然后求SA 显然每个相同子串都是一个后缀的前缀,所以枚举s1的每个后缀的最长和s2相同的前缀串(直接在排序后的数组里挨个找,最近的两个分别属于s1和s2的后 ...
- 【BZOJ3796】Mushroom追妹纸 二分+hash
[BZOJ3796]Mushroom追妹纸 Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决 ...
- 【bzoj3796】Mushroom追妹纸 hash/sa+kmp+二分
Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意--写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他从网上找到了两篇极佳的情书, ...
- BZOJ3796 : Mushroom追妹纸
将S1与S2用#号拼接在一起形成S串 将S3与S串跑KMP求出S3在S串中每次出现的位置l[i] 对于S串每个后缀i,求出f[i]表示该串不包含S3串的最长前缀 然后求出S串的后缀数组 先从小到大扫描 ...
随机推荐
- ORACLE数据删除数据删除的解决办法
今天主要以oracle数据库为例,介绍关于表中数据删除的解决办法.(不考虑全库备份和利用归档日志)删除表中数据有三种方法:·delete(删除一条记录)·drop或truncate删除表格中数据 1. ...
- Coursera Algorithms Programming Assignment 5: Kd-Trees (98分)
题目地址:http://coursera.cs.princeton.edu/algs4/assignments/kdtree.html 分析: Brute-force implementation. ...
- D. Toy Sum(cf)
http://codeforces.com/problemset/problem/405/D 题意:已知集合S={1,2,3......1000000},s=1000000,从集合S中选择n个数,X= ...
- 如何使jquery性能最佳
转自 http://www.cnblogs.com/mo-beifeng/archive/2012/02/02/2336228.html 1. 使用最新版本的jQuery jQuery的版本更新很快, ...
- linux tmux基本操作
1. 安装工具 Centos : yum install tmux 2. 基本操作 新建会话:tmux new -s session-name 查看会话:tmux ls 进入会话:tmux a -t ...
- 安卓5.0新特性之Palette
根据图片来决定标题的颜色和标题栏的背景色,这样视觉上更具有冲击力和新鲜感,而不像统一色调那样呆板. Palette这个类能提取以下突出的颜色: Vibrant(充满活力的) Vibrant dark( ...
- OI——不后悔的两年
NOI2014,悲惨的考跪,99+170+130 399 Cu滚粗.最终签到了复旦的一本,还算是有点结果吧.(其实我一开始就想读复旦我会说?)回首这两年,就像一场梦一样,从一无所知的小白到进入省队再到 ...
- ACM_出题人这样不好吧
出题人这样不好吧 Time Limit: 2000/1000ms (Java/Others) Problem Description: 作为编协的第一次月赛,肯定是要有防AK(ALL KILL)的题目 ...
- ACM_尿裤子
Problem Description: 小X上课的时候喝了一大壶水,午饭后他极限跑回宿舍上厕所,结果发现不知道哪个逗比舍友在宿舍门上加了一把4位密码锁,然后还留了纸条:密码是6666,小X只能一个一 ...
- 在Django中使用redis:包括安装、配置、启动。
一.安装redis: 1.下载: wget http://download.redis.io/releases/redis-3.2.8.tar.gz 2.解压 tar -zxvf redis-.tar ...