bzoj4032: [HEOI2015]最短不公共子串(SAM+DP)
4032: [HEOI2015]最短不公共子串
题目:传送门
题解:
陈年老题良心%你赛膜爆嘎爷
当初做题...一眼SAM...结果只会两种直接DP的情况...
情况1: 直接设f[i][j] 表示的是a串的第i个位置和b串的第j个位置开始的最长公共前缀(灵感来源于SA)。然后就枚举开头直接瞎搞啊。。。
情况2: 定义一个last[i][j] 表示b串的位置i后面的第一个字符j,贪心的思想直接做,匹配不到位置就直接记录答案了嘛
情况3: 因为是在b串当中找子串,a中找子序列,那就考虑对b建SAM,然后定义da[] 表示的是a串的第i个位置结尾的串在b串中跑到第j个状态的最短长度(具体看代码)、
情况4: 利用情况2预处理的last,贪心思想,仿照情况三把last当作自动机来跑
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define inf 1e9
using namespace std;
struct SAM
{
int son[];
}ch[];int cnt,dep[],a[],fail[],da[],la,root,ss;、
//da 表示的是a串的第i个位置结尾的串在b串中跑到第j个状态的最短长度
void add(int k)
{
int x=a[k];
int p=la,np=++cnt;dep[np]=k;
while(p!= && ch[p].son[x]==)ch[p].son[x]=np,p=fail[p];
if(p==)fail[np]=root;
else
{
int q=ch[p].son[x];
if(dep[p]+==dep[q])fail[np]=q;
else
{
int nq=++cnt;dep[nq]=dep[p]+;
ch[nq]=ch[q];fail[nq]=fail[q];fail[np]=fail[q]=nq;
while(p && ch[p].son[x]==q)ch[p].son[x]=nq,p=fail[p];
}
}
la=np;
}
int len1,len2,opt;
int c[],last[][];//位置i后面的第一个字符j
char sa[],sb[];
int f[][];//分别以i,j位置开头的最长公共前缀
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
//scanf("%d",&opt);
scanf("%s",sa+);len1=strlen(sa+);
scanf("%s",sb+);len2=strlen(sb+);
//if(opt==1)
//{
memset(f,,sizeof(f));int ans=inf,len=,maxx=;
for(int i=len1;i>=;i--)for(int j=len2;j>=;j--)if(sa[i]==sb[j])f[i][j]=f[i+][j+]+;
for(int i=;i<=len1;i++)
{
maxx=;for(int j=;j<=len2;j++)maxx=max(maxx,f[i][j]);
if(maxx!=len1-i+)ans=min(ans,maxx+);//加一定不相等
}
if(ans==inf)printf("-1\n");
else printf("%d\n",ans);
//}
//else if(opt==2)
//{
len=,ans=inf;for(int i=;i<=;i++)c[i]=inf;sb[]='a';
for(int i=len2;i>=;i--){for(int j=;j<=;j++)last[i][j]=c[j];c[sb[i]-'a'+]=i;}
for(int i=;i<=len1;i++)
{
len=;
for(int j=i;j<=len1;j++)
{
len=last[len][sa[j]-'a'+];
if(len>len1){ans=min(ans,j-i+);break;}//跳出去证明没有了
}
}
if(ans==inf)printf("-1\n");
else printf("%d\n",ans);
//}
// else if(opt==3)
// {
cnt=;root=la=++cnt;memset(da,,sizeof(da));
for(int i=;i<=len2;i++)a[i]=sb[i]-'a';for(int i=;i<=len2;i++)add(i);ss=;da[]=;ans=inf;
for(int i=;i<=len1;i++)
for(int j=;j<=cnt;j++)
{
ss=ch[j].son[sa[i]-'a'];
if(ss==)ans=min(ans,da[j]+);else da[ss]=min(da[ss],da[j]+);
}
if(ans==inf)printf("-1\n");
else printf("%d\n",ans);
// }
//else if(opt==4)
//{
ans=inf;//for(int i=1;i<=50;i++)c[i]=inf;sb[0]='a';
//for(int i=len2;i>=0;i--){for(int j=1;j<=26;j++)last[i][j]=c[j];c[sb[i]-'a'+1]=i;}
memset(da,,sizeof(da));da[]=;ss=;
for(int i=;i<=len1;i++)
for(int j=len2;j>=;j--)
{
ss=last[j][sa[i]-'a'+];
if(ss>len1)ans=min(ans,da[j]+);else da[ss]=min(da[ss],da[j]+);
}
if(ans==inf)printf("-1\n");
else printf("%d\n",ans);
//}
return ;
}
bzoj4032: [HEOI2015]最短不公共子串(SAM+DP)的更多相关文章
- [BZOJ4032][HEOI2015]最短不公共子串(Trie+DP)
在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之——被它们虐. 操作一:对A,B分别建SAM,暴力BFS. 操作二:对B建序列自动机或SAM,A在上面暴力匹配. 操作三:对A,B建 ...
- BZOJ4032:[HEOI2015]最短不公共子串(SAM)
Description 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列” ...
- luoguP4112 [HEOI2015]最短不公共子串 SAM,序列自动机,广搜BFS
luoguP4112 [HEOI2015]最短不公共子串 链接 luogu loj 思路 子串可以用后缀自动机,子序列可以用序列自动机. 序列自动机是啥,就是能访问到所有子序列的自动机. 每个点记录下 ...
- BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...
- BZOJ4032: [HEOI2015]最短不公共子串(后缀自动机+序列自动机)
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...
- BZOJ4032 [HEOI2015]最短不公共子串 【后缀自动机 + 序列自动机 + dp】
题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz ...
- bzoj 4032: [HEOI2015]最短不公共子串【dp+SAM】
第一.二问: 就是最小的最长公共长度+1,设f[i][j]为a匹配到i,b匹配到j,第一问的转移是f[i][j]=(a[i]==b[j]?f[i-1][j-1]+1:0),第二问的转移是f[i][j] ...
- BZOJ4032 : [HEOI2015]最短不公共子串
第一问: 对B串建立SAM,暴力枚举A的每个子串,在SAM上走,若失配则可行. 第二问: 设g[i][j]表示B串的第i个字符之后最早出现的字符j的位置,暴力枚举A的每个子串,按照g贪心地走,若失配则 ...
- bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)
bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...
随机推荐
- Irrlicht 1.8.4 + Win7 + VC2015 + x64 +OpenGL编译
1. 下载irrlicht1.8.4 https://nchc.dl.sourceforge.net/project/irrlicht/Irrlicht%20SDK/1.8/1.8.4/irrlich ...
- 图片文字滚动插件jQuery Scrollbox
图片文字滚动插件jQuery Scrollbox附件中提供了五种图片.文字滚动样式,只需调用jquery库和jQuery Scrollbox插件,然后再加一段简单的jquery代码即可使用,兼容性良好 ...
- Redux入门
Redux入门 本文转载自:众成翻译 译者:miaoYu 链接:http://www.zcfy.cc/article/4728 原文:https://bumbu.github.io/simple-re ...
- JavaScript实现延时提示框
<html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...
- Bin文件
那什么是bin文件呢?为什么这么关键? bin (binary)既是:二进制, 里面存放的一般是可执行的二进制文件.二进制即是机器代码,汇编语言编译后的结果.我们编译的是高级语言,把高级语言翻译为机器 ...
- Oracle"TNS监听程序找不到符合协议堆栈要求的可用处理程序"解决方案
问题描述:在使用ETL工具通过odbc方式连接Oracle进行数据抽取的过程中,Oracle 监听日志报错如下: 根本原因就是Oracle的process和session已经达到了甚至超过了最大值,解 ...
- TRS矩阵分解
transform = TRS T就是transform的最后一列.关于R和S的分解,PBRT给了一个公式:M_(i+1) = (M_i + ((M_i)^T)^(-1))*0.5,直到M收敛.M初始 ...
- 定时器篇---java.util.TimerTask和quartz
最近项目中出现了定时执行任务的东西,研究了一下,觉得挺不错的,以后还用得到,就总结了下. 这里只介绍两种java.util.Timer 和 quartz java.util.Timer java自带的 ...
- 【前端分享】jQuery.lazyload详解(转)
jQuery实现图片延迟加载,不知道是否可以节省带宽呢?有人知道吗?这究竟只是一个视觉特效还是真的能延迟加载减少服务器的请求呢? <script type="text/javascri ...
- 文字横向滚动marquee
<div style="width:200px; height:300px"> <marquee behavior="scroll" cont ...