[BZOJ3796]Mushroom追妹纸:后缀自动机+KMP
分析
这道题有个\(O(n)\)的后缀自动机做法,感觉很好理解就在这说一下。
先对\(s1\)和\(s2\)求最长公共子串,对于\(s2\)的每一个下标\(i\),求一个\(f[i]\)表示以\(s2[i]\)结尾的最长匹配长度。
KMP求出\(s3\)在\(s2\)上的所有结束位置,然后扫一遍\(s2\)统计答案,很简单。
代码
#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl;
const int MAXN=50005;
int len1,len2,len3,las,tot,maxlen[MAXN],nxt[MAXN];
char s1[MAXN],s2[MAXN],s3[MAXN];
bool mat[MAXN];
struct sam{
int fa,to[26];
int len;
}a[MAXN<<1];
void extend(int c){
int p=las,np=++tot;las=np,a[np].len=a[p].len+1;
while(p&&!a[p].to[c]) a[p].to[c]=np,p=a[p].fa;
if(!p){a[np].fa=1;return;}
int q=a[p].to[c];
if(a[p].len+1==a[q].len){a[np].fa=q;return;}
int nq=++tot;a[nq]=a[q],a[nq].len=a[p].len+1,a[np].fa=a[q].fa=nq;
while(p&&a[p].to[c]==q) a[p].to[c]=nq,p=a[p].fa;
}
void kmp(){
nxt[1]=0;
for(register int i=2,j=0;i<=len3;++i){
while(j&&s3[i]!=s3[j+1]) j=nxt[j];
if(s3[i]==s3[j+1]) ++j;
nxt[i]=j;
}
for(register int i=1,j=0;i<=len2;++i){
while(j&&s2[i]!=s3[j+1]) j=nxt[j];
if(s2[i]==s3[j+1]) ++j;
if(j==len3){
mat[i]=true;
j=nxt[j];
}
}
}
void solve(){
int now=1,cur=0;
rin(i,1,len2){
while(now&&!a[now].to[s2[i]-'a']) now=a[now].fa,cur=a[now].len;
if(!now){now=1,cur=0;continue;}
now=a[now].to[s2[i]-'a'],++cur;
maxlen[i]=cur;
}
}
int main(){
scanf("%s",s1+1);
getchar();
scanf("%s",s2+1);
getchar();
scanf("%s",s3+1);
len1=strlen(s1+1);
len2=strlen(s2+1);
len3=strlen(s3+1);
las=tot=1;
rin(i,1,len1) extend(s1[i]-'a');
kmp();
solve();
int ans=0,lim=1e9;
rin(i,1,len2){
if(mat[i]) lim=len3-1;
ans=std::max(ans,std::min(maxlen[i],lim++));
}
printf("%d\n",ans);
return 0;
}
[BZOJ3796]Mushroom追妹纸:后缀自动机+KMP的更多相关文章
- BZOJ3796 Mushroom追妹纸 字符串 SA KMP
原文链接https://www.cnblogs.com/zhouzhendong/p/9253173.html 题目传送门 - BZOJ3796 题意 找一个串 $w$ 满足: 1.$w$ 是 $s_ ...
- 【bzoj3796】Mushroom追妹纸 hash/sa+kmp+二分
Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意--写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他从网上找到了两篇极佳的情书, ...
- bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp
题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...
- BZOJ3796 Mushroom追妹纸(二分答案+后缀数组+KMP)
求出一个串使得这个串是\(s1,s2\)的子串.串中不包含\(s3\). 如果没有这个\(s3\)就可以二分答案,然后height小于二分值分一组.看看每组里是不是出现过\(s1,s2\)的后缀.判断 ...
- BZOJ3796 : Mushroom追妹纸
将S1与S2用#号拼接在一起形成S串 将S3与S串跑KMP求出S3在S串中每次出现的位置l[i] 对于S串每个后缀i,求出f[i]表示该串不包含S3串的最长前缀 然后求出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 的匹配情况: 注意 ...
- 【BZOJ3796】Mushroom追妹纸 二分+hash
[BZOJ3796]Mushroom追妹纸 Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决 ...
- [BZOJ 3796]Mushroom追妹纸
[BZOJ 3796]Mushroom追妹纸 题目 Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他 ...
随机推荐
- Vuejs——slot内容分发
①概述: 简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示.不显示.在哪个地方显示.如何显示,就是slot分发负责的活. ②默认情况下父组件在子组件内套的内容,是不显示的. 例如代 ...
- sql server 幂运算函数power(x,y)、square(x)、exp(x)
--POWER(x,y)函数返回x的y次乘方的结果值 --SQUARE(x)函数返回指定浮点值x的平方 --EXP(x)函数返回e的x乘方后的值 示例:select POWER(2,2), POWER ...
- 解决:centos配置ssh免密码登录后仍要输入密码
转自https://www.jb51.net/article/121180.htm 第一步:在本机中创建秘钥 1.执行命令:ssh-keygen -t rsa 2.之后一路回车就行啦:会在-(home ...
- CVS文件导出
/** * @param $filename 文件名 */ public function exportCxv($filename) { $filename = @iconv('UTF-8', 'GB ...
- python 父子节点生成字典
lines = [(1, 1, '父1节点'), (2, 1, '1-2'), (3, 1, '1-3'), (4, 3, '1-3-4'), (5, 3, '1-3-5'), (6, 3, '1-3 ...
- windows挂载nfs
注意:Win10 Creators Update前只有Win10企业版可以挂载NFS, Creators Update后专业版也可挂载NFS了. 安装 按Win+R输入OptionalFeatures ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(6)|变量绑定]
[易学易懂系列|rustlang语言|零基础|快速入门|(6)] 有意思的基础知识 变量绑定 我们现在回过头来看看,一些基础知识. 因为理解了前面的重要概念:所有权,借用,生命周期. 我们现在看基础知 ...
- 如何创建DLL,以及注入DLL
为了防止忘记,特记下 DLL的创建,在VS2017中选择dll的创建 // dllmain.cpp : Defines the entry point for the DLL application. ...
- spring boot 2.0(三)使用docker部署springboot
Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...
- 【CF896C】Willem, Chtholly and Seniorious
ODT模板题,ODT适合随机数据下具有维护区间推平操作的序列维护题目,时间复杂度较为玄学.. 代码如下 #include <bits/stdc++.h> #define pb push_b ...