题目: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 ] 最短不公共子串 —— 后缀自动机+序列自动机的更多相关文章

  1. 解题:HEOI 2015 最短不公共子串

    题面 制杖四合一,HEOI以前居然出这种**题,看来HE还是联考比较好= = 首先对第二个串建SAM 第一个简单,以每个位置为起点在SAM上走,失配时更新答案 第二个先在第二个串上预处理$firs[i ...

  2. bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)

    bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...

  3. BZOJ 4032: [HEOI2015]最短不公共子串 后缀自动机 暴力

    4032: [HEOI2015]最短不公共子串 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4032 Description 在虐各种最 ...

  4. bzoj 4032 [HEOI2015]最短不公共子串——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4032 不是 b 的子串的话就对 b 建后缀自动机,在 a 上枚举从每个位置开始的子串或者找子 ...

  5. BZOJ 4032: [HEOI2015]最短不公共子串(后缀自动机+记忆化搜索)

    传送门 解题思路 首先需要预处理两个串\(nxt(i)(j)\)表示i位置之后最近的\(j\). 第一问直接对\(b\)建后缀自动机,枚举\(a\)的起点暴力匹配. 第二问枚举\(a\)的起点,\(b ...

  6. BZOJ 4032: [HEOI2015]最短不公共子串

    4032: [HEOI2015]最短不公共子串 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 446  Solved: 224[Submit][Sta ...

  7. 【BZOJ】4032: [HEOI2015]最短不公共子串(LibreOJ #2123)

    [题意]给两个小写字母串A,B,请你计算: (1) A的一个最短的子串,它不是B的子串 (2) A的一个最短的子串,它不是B的子序列 (3) A的一个最短的子序列,它不是B的子串 (4) A的一个最短 ...

  8. 【BZOJ4032】[HEOI2015]最短不公共子串(后缀自动机,序列自动机)

    [BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\) ...

  9. bzoj4032: [HEOI2015]最短不公共子串(SAM+DP)

    4032: [HEOI2015]最短不公共子串 题目:传送门 题解: 陈年老题良心%你赛膜爆嘎爷 当初做题...一眼SAM...结果只会两种直接DP的情况... 情况1: 直接设f[i][j] 表示的 ...

随机推荐

  1. 一文了解ConfigurationConditon接口

    ConfigurationCondition 接口说明 @Conditional 和 Condition ​ 在了解ConfigurationCondition 接口之前,先通过一个示例来了解一下@C ...

  2. ubantu 下 修改mysql 默认编码

    启动mysql后,以root登录mysql root@Eadgar-virtual-machine:~# mysql -uroot -proot mysql> show variables li ...

  3. uboot生成随机的MAC地址

    转载:http://blog.chinaunix.net/uid-25885064-id-3303132.html 在使用U-boot时,有个问题就是MAC地址的设置,如果MAC地址相同的两块开发板在 ...

  4. NUTCH2.3 hadoop2.7.1 hbase1.0.1.1 solr5.2.1部署(二)

     Precondition: hadoop 2.7.1 hbase 1.0.1.1 / hbase 0.98.13 192.168.1.106 ->master 192.168.1.105 ...

  5. iOS:苹果企业证书通过网页分发安装app

    本文转载至 http://blog.sina.com.cn/s/blog_6afb7d800101fa16.html 苹果的企业级证书发布的应用,是不用设备授权即可直接安装,并且不限设备上限.为了方便 ...

  6. Ioc容器Autofac系列

    1.http://blog.csdn.net/xingxing513234072/article/details/9211969 2.asp.net mvc中整合autofachttp://blog. ...

  7. Socket 群聊功能

    1.Server端: 拥有一个存放与客户端连接对象的List<socket> 有一个客户端发信息后 遍历List 实现群发功能 代码如下: package com.socket; impo ...

  8. HttpClient 访问 https 出现peer can't

    package util; import java.security.cert.CertificateException; import javax.net.ssl.SSLContext;import ...

  9. imagecopyresampled()改变图片大小后质量要比imagecopyresized()高。

    php程序中改变图片大小的函数大多数人都想到用imagecopyresized(),不过经过测试比较发现,使用imagecopyresampled()改变的图片质量更高. 下面我们来看看两者的比较结果 ...

  10. 蓝牙 CTS 测试

    安装蓝牙测试安装包 之后  . 安卓包名字 android-cts-6.0_r19-linux_x86-x86.zip 解压之后 /cts/android-cts/tools/  目录下 运行  ./ ...