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)的更多相关文章

  1. [BZOJ4032][HEOI2015]最短不公共子串(Trie+DP)

    在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之——被它们虐. 操作一:对A,B分别建SAM,暴力BFS. 操作二:对B建序列自动机或SAM,A在上面暴力匹配. 操作三:对A,B建 ...

  2. BZOJ4032:[HEOI2015]最短不公共子串(SAM)

    Description 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列” ...

  3. luoguP4112 [HEOI2015]最短不公共子串 SAM,序列自动机,广搜BFS

    luoguP4112 [HEOI2015]最短不公共子串 链接 luogu loj 思路 子串可以用后缀自动机,子序列可以用序列自动机. 序列自动机是啥,就是能访问到所有子序列的自动机. 每个点记录下 ...

  4. BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

  5. BZOJ4032: [HEOI2015]最短不公共子串(后缀自动机+序列自动机)

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

  6. BZOJ4032 [HEOI2015]最短不公共子串 【后缀自动机 + 序列自动机 + dp】

    题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz ...

  7. 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] ...

  8. BZOJ4032 : [HEOI2015]最短不公共子串

    第一问: 对B串建立SAM,暴力枚举A的每个子串,在SAM上走,若失配则可行. 第二问: 设g[i][j]表示B串的第i个字符之后最早出现的字符j的位置,暴力枚举A的每个子串,按照g贪心地走,若失配则 ...

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

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

随机推荐

  1. 43.qt通过qss自定义外观

    样式: 文件格式类型: candy.qss /* R1 */ QDialog { /*设置背景图片*/ background-image: url(:/images/background.png); ...

  2. C# 同步更新系统时间

    前言 在定位用户问题时,发现有些电脑,会出现系统时间不是最新的问题. 可能原因: 取消了勾选服务器时间同步 当前安装的系统,是一个未知来源系统,导致系统时间更新失败 而系统时间不正确,会导致IE选项- ...

  3. 如何在C#中运行数学表达式字符串

    方法1:利用DataTable中的Compute方法 1 string expression = "1+2*3"; 2 DataTable eval = new DataTable ...

  4. .net web api跨域问题

    No 'Access-Control-Allow-Origin' Ajax跨域访问解决方案   No 'Access-Control-Allow-Origin' header is present o ...

  5. C-概览

    1.贝尔实验室的Dennis Ritchie在1972年开发了C语言,C来自于Ken Thompson的B语言.当时Ritchie正与 Thompson一起设计UNIX操作系统. 2.C是面向过程的编 ...

  6. Unity3d transform

    using UnityEngine; using System.Collections; public class transform : MonoBehaviour { // Use this fo ...

  7. 依赖注入与Service Locator

    为什么需要依赖注入? ServiceUser是组件,在编写者之外的环境内被使用,且使用者不能改变其源代码. ServiceProvider是服务,其类似于ServiceUser,都要被其他应用使用,不 ...

  8. 杭电1229 还是A+B

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1229 解题思路,最开始想的是把输入的数据存入数组中,比如输入 1,在数组中就储存为1000(因为数据不 ...

  9. (转)shiro权限框架详解05-shiro授权

    http://blog.csdn.net/facekbook/article/details/54910606 本文介绍 授权流程 授权方式 授权测试 自定义授权realm 授权流程 开始构造Secu ...

  10. win 2016 添加系统组件注册表,

    Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ServerManager\ServicingS ...