bzoj 4032 [ HEOI 2015 ] 最短不公共子串 —— 后缀自动机+序列自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4032
序列自动机其实就是每个位置记录一下某字母后面第一个出现位置,为了子序列能尽量长。
对字符串B建一个后缀自动机,一个序列自动机,然后让A在上面找即可;
1.枚举A每个位置开始的子串,在SAM上走,失配就找到了;
2.枚举A子串,用B的序列自动机找失配处;
3.设 f[i][j] 表示A串前 i 个字符形成的子序列对应SAM上节点 j 时的最短子序列长度,可以转移;
4.f[i][j] 表示A串前 i 个字符的子序列对应B串第 j 个位置时的最短子序列长度,用序列自动机转移;
所以注意 f[i][j] 的第二维要开 4000!否则不是 MLE 而是 WA 。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const xn=,inf=0x3f3f3f3f;
int fa[xn<<],l[xn<<],go[xn<<][],lst=,cnt=,f[xn][xn<<],g[xn][],nxt[];//<<1!!
char s1[xn],s2[xn];
void add(int w)
{
int p=lst,np=++cnt; lst=np; l[np]=l[p]+;
for(;p&&!go[p][w];p=fa[p])go[p][w]=np;
if(!p)fa[np]=;
else
{
int q=go[p][w];
if(l[q]==l[p]+)fa[np]=q;
else
{
int nq=++cnt; l[nq]=l[p]+;
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
for(;go[p][w]==q;p=fa[p])go[p][w]=nq;
}
}
}
int main()
{
scanf("%s",s1+); int l1=strlen(s1+);
scanf("%s",s2+); int l2=strlen(s2+);
for(int i=;i<=l1;i++)s1[i]-='a';
for(int i=;i<=l2;i++)s2[i]-='a';
for(int i=;i<=l2;i++)add(s2[i]);
for(int i=;i<;i++)nxt[i]=l2+;
for(int i=l2;i>=;i--)
{
for(int j=;j<;j++)g[i][j]=nxt[j];
nxt[s2[i]]=i;
} int ans=inf;
for(int i=;i<=l1;i++)
{
int p=,j;
for(j=i;j<=l1;j++)
{
if(!go[p][s1[j]])break;
p=go[p][s1[j]];
}
if(j<=l1)ans=min(ans,j-i+);
}
if(ans==inf)ans=-; printf("%d\n",ans); ans=inf;
for(int i=;i<=l1;i++)
{
if(g[][s1[i]]>l2){ans=min(ans,); continue;}
int p=g[][s1[i]],j;
for(j=i+;j<=l1;j++)
{
if(g[p][s1[j]]==l2+)break;
p=g[p][s1[j]];
}
if(j<=l1)ans=min(ans,j-i+);
}
if(ans==inf)ans=-; printf("%d\n",ans); memset(f,0x3f,sizeof f); f[][]=; ans=inf;
for(int i=;i<l1;i++)
for(int j=,p;j<=cnt;j++)
{
if(f[i][j]==inf)continue;
f[i+][j]=min(f[i+][j],f[i][j]);
if((p=go[j][s1[i+]]))f[i+][p]=min(f[i+][p],f[i][j]+);//,printf("%d %d p=%d\n",j,s1[i+1],p);
else ans=min(ans,f[i][j]+);
}
if(ans==inf)ans=-; printf("%d\n",ans); memset(f,0x3f,sizeof f); f[][]=; ans=inf;
for(int i=;i<l1;i++)
for(int j=,p;j<=l2;j++)
{
if(f[i][j]==inf)continue;
f[i+][j]=min(f[i+][j],f[i][j]);
if((p=g[j][s1[i+]])<l2+)f[i+][p]=min(f[i+][p],f[i][j]+);
else ans=min(ans,f[i][j]+);
}
if(ans==inf)ans=-; printf("%d\n",ans);
return ;
}
bzoj 4032 [ HEOI 2015 ] 最短不公共子串 —— 后缀自动机+序列自动机的更多相关文章
- 解题:HEOI 2015 最短不公共子串
题面 制杖四合一,HEOI以前居然出这种**题,看来HE还是联考比较好= = 首先对第二个串建SAM 第一个简单,以每个位置为起点在SAM上走,失配时更新答案 第二个先在第二个串上预处理$firs[i ...
- bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)
bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...
- BZOJ 4032: [HEOI2015]最短不公共子串 后缀自动机 暴力
4032: [HEOI2015]最短不公共子串 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4032 Description 在虐各种最 ...
- bzoj 4032 [HEOI2015]最短不公共子串——后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4032 不是 b 的子串的话就对 b 建后缀自动机,在 a 上枚举从每个位置开始的子串或者找子 ...
- BZOJ 4032: [HEOI2015]最短不公共子串(后缀自动机+记忆化搜索)
传送门 解题思路 首先需要预处理两个串\(nxt(i)(j)\)表示i位置之后最近的\(j\). 第一问直接对\(b\)建后缀自动机,枚举\(a\)的起点暴力匹配. 第二问枚举\(a\)的起点,\(b ...
- BZOJ 4032: [HEOI2015]最短不公共子串
4032: [HEOI2015]最短不公共子串 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 446 Solved: 224[Submit][Sta ...
- 【BZOJ】4032: [HEOI2015]最短不公共子串(LibreOJ #2123)
[题意]给两个小写字母串A,B,请你计算: (1) A的一个最短的子串,它不是B的子串 (2) A的一个最短的子串,它不是B的子序列 (3) A的一个最短的子序列,它不是B的子串 (4) A的一个最短 ...
- 【BZOJ4032】[HEOI2015]最短不公共子串(后缀自动机,序列自动机)
[BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\) ...
- bzoj4032: [HEOI2015]最短不公共子串(SAM+DP)
4032: [HEOI2015]最短不公共子串 题目:传送门 题解: 陈年老题良心%你赛膜爆嘎爷 当初做题...一眼SAM...结果只会两种直接DP的情况... 情况1: 直接设f[i][j] 表示的 ...
随机推荐
- anaconda3.5 3.6 2.7
https://repo.continuum.io/archive/ Filename Size Last Modified MD5 Anaconda2-5.0.1-Linux-x86.sh 413. ...
- python之prettytable
sdata={'语文':89,'数学':96,'音乐':39,'英语':78,'化学':88} #字典向Series转化 >>> studata=Series(sdata) > ...
- java中BigDecimal的学习
干着java的活,但是看的都是一些偏底层的东西(或者我根本就没有看),有点荒废了java的学习. 最近一直在用到一个类是BigDecimal,但都是模棱两可地在那儿用,并没有深入研究这个类的细节,感觉 ...
- HDU3549_Flow Problem(网络流/EK)
Flow Problem Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- Python 时间格式化(转)
From:http://www.cnblogs.com/65702708/archive/2011/04/17/2018936.html http://www.wklken.me/posts/2015 ...
- 再说WCF Data Contract KnownTypeAttribute
WCF 中的序列化是用DataContractSerializer,所有被[DataContract]和[DataMemeber]标记的类和属性会被DataContractSerializer序列化. ...
- yum 安装apache php 使php支持memcached扩展
在公司上新项目的时候,无论生产环境还是测试环境,都会让运维安装php 环境(lamp/lnmp),并让php支持memcached 的扩展.这里搭建php环境其实主要就是搭建apache 和php.m ...
- tp框架知识 之(链接数据库和操作数据内容)
框架有时会用到数据库的内容,在"ThinkPhp框架知识"的那篇随笔中提到过,现在这篇随笔详细的描述下. 一.链接数据库 (1)找到模块文件夹中的Conf文件夹,然后进行编写con ...
- 申请edu邮箱
https://blog.csdn.net/w305607610/article/details/86771593 手把手教你申请CCC(City Colleges of Chicago)教育邮箱 台 ...
- android菜鸟学习笔记8----Activity(一)
Activity是android应用程序中重要的组件之一,常听到的android四大组件是Activity.Service.BroadcastReceiver和ContentProvider.它间接继 ...