P4112 [HEOI2015]最短不公共子串

题目描述

在虐各种最长公共子串、子序列的题虐的不耐烦了之后,你决定反其道而行之。

一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是。

一个串的“子序列”指的是它的可以不连续的一段,例如bde是abcdef的子串,但bdd不是。

下面,给两个小写字母串A,B,请你计算:

(1) A的一个最短的子串,它不是B的子串

(2) A的一个最短的子串,它不是B的子序列

(3) A的一个最短的子序列,它不是B的子串

(4) A的一个最短的子序列,它不是B的子序列

输入输出格式

输入格式:

有两行,每行一个小写字母组成的字符串,分别代表A和B。

输出格式:

输出4行,每行一个整数,表示以上4个问题的答案的长度。如果没有符合要求的答案,输出-1

说明

对于20%的数据,A和B的长度都不超过20

对于50%的数据,A和B的长度都不超过500

对于100%的数据,A和B的长度都不超过2000


四合一还行。

问题1

建立B的后缀自动机

枚举A的开头,然后在B上从S向后跑,失配了更新答案

问题2

建立B的序列自动机

然后一样的

问题3

在B的后缀自动机上跑DP(这样才能处理A的子序列)

具体的\(dp_i\)表示这个点可以匹配上的最短长度

从头开始枚举每个点更新。

问题4

在B的序列自动机上跑,其他和三一样

数据太水,3,4的dp01背包写成完全背包也可以过...

我3的dp写的是假的,懒得改了..


Code:

#include <cstdio>
#include <cstring>
const int N=4010;
const int inf=0x3f3f3f3f;
char s1[N],s2[N];
int n,dp[N];
int min(int x,int y){return x<y?x:y;}
struct SuffixAutomata
{
int tot,las,len[N],ch[N][26],par[N];
SuffixAutomata()
{
tot=las=1;
memset(len,0,sizeof(len));
memset(ch,0,sizeof(ch));
memset(par,0,sizeof(par));
}
void extend(int c)
{
int now=++tot,p=las;
len[now]=len[p]+1;
while(p&&!ch[p][c]) ch[p][c]=now,p=par[p];
if(!p) par[now]=1;
else
{
int x=ch[p][c];
if(len[x]==len[p]+1) par[now]=x;
else
{
int y=++tot;
len[y]=len[p]+1,par[y]=par[x];
memcpy(ch[y],ch[x],sizeof ch[y]);
while(p&&ch[p][c]==x) ch[p][c]=y,p=par[p];
par[now]=par[x]=y;
}
}
las=now;
}
void build(char *s)
{
int n=strlen(s+1);
for(int i=1;i<=n;i++) extend(s[i]-'a');
}
}T1;
struct SequentialAutomaton
{
int suc[N],ch[N][26];
SequentialAutomaton()
{
memset(suc,0,sizeof(suc));
memset(ch,0,sizeof(ch));
}
void build(char *s)
{
int n=strlen(s+1);s[0]='a';
for(int i=n;~i;i--)
{
for(int j=0;j<26;j++)
if(suc[j])
ch[i][j]=suc[j];
suc[s[i]-'a']=i;
}
}
}T2;
void work1()
{
int ans=inf;
for(int i=1;i<=n;i++)
{
int now=1;
for(int j=i;j<=n;j++)
{
int c=s1[j]-'a';
if(T1.ch[now][c]) now=T1.ch[now][c];
else
{
ans=min(ans,j+1-i);
break;
}
}
}
if(ans==inf) puts("-1");
else printf("%d\n",ans);
}
void work2()
{
int ans=inf;
for(int i=1;i<=n;i++)
{
int now=0;
for(int j=i;j<=n;j++)
{
int c=s1[j]-'a';
if(T2.ch[now][c]) now=T2.ch[now][c];
else
{
ans=min(ans,j+1-i);
break;
}
}
}
if(ans==inf) puts("-1");
else printf("%d\n",ans);
}
void work3()
{
memset(dp,0x3f,sizeof dp);
dp[1]=0;
int ans=inf;
for(int i=1;i<=n;i++)
{
int c=s1[i]-'a';
for(int j=1;j<=T1.tot;j++)
{
int v=T1.ch[j][c];
if(v) dp[v]=min(dp[v],dp[j]+1);
else ans=min(ans,dp[j]+1);
}
}
if(ans==inf) puts("-1");
else printf("%d\n",ans);
}
void work4()
{
memset(dp,0x3f,sizeof dp);
dp[0]=0;
int ans=inf;
for(int i=1;i<=n;i++)
{
int c=s1[i]-'a';
for(int j=n;~j;j--)
{
int v=T2.ch[j][c];
if(v) dp[v]=min(dp[v],dp[j]+1);
else ans=min(ans,dp[j]+1);
}
}
if(ans==inf) puts("-1");
else printf("%d\n",ans);
}
int main()
{
scanf("%s%s",s1+1,s2+1);
T1.build(s2),T2.build(s2),n=strlen(s1+1);
work1(),work2(),work3(),work4();
return 0;
}

2019.1.7

洛谷 P4112 [HEOI2015]最短不公共子串 解题报告的更多相关文章

  1. BZOJ 4032 Luogu P4112 [HEOI2015]最短不公共子串 (DP、后缀自动机)

    这其实是道水题... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4032 (luogu)https://www.luog ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 大数据入门第二十三天——SparkSQL(一)入门与使用

    一.概述 1.什么是sparkSQL 根据官网的解释: Spark SQL is a Spark module for structured data processing. 也就是说,sparkSQ ...

  2. 2017-2018-2 20155315《网络对抗技术》Exp8 :Web基础

    实验目的 理解HTML,学会Web前端.Web后端和数据库编程及SQL注入.XSS攻击测试 教程 实验内容 操作程序规律 运行脚本或可执行文件 查看配置文件 出错找日志 Web前端HTML 能正常安装 ...

  3. mfc CFileDialog类

    知识点: CFileDialog类 SetBitmap LoadImage 动态显示图片 一.CFileDialog类 构造函数 CFileDialog( BOOL bOpenFileDialog, ...

  4. [Deep-Learning-with-Python]基于Kears的Reuters新闻分类

    Reuters数据集下载速度慢,可以在我的repo库中找到下载,下载后放到~/.keras/datasets/目录下,即可正常运行. 构建神经网络将路透社新闻分类,一共有46个类别.因为有多个类别,属 ...

  5. springtest mapper注入失败问题解决 {@org.springframework.beans.factory.annotation.Autowired(required=true)}

    花费了一下午都没有搜索到相关解决方案的原因,一是我使用的 UnsatisfiedDependencyException 这个比较上层的异常(在最前面)来进行搜索, 范围太广导致没有搜索到,而且即便是有 ...

  6. ElasticSearch入门 第四篇:使用C#添加和更新文档

    这是ElasticSearch 2.4 版本系列的第四篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  7. Partition4:增加分区

    在关系型 DB中,分区表经常使用DateKey(int 数据类型)作为Partition Column,每个月的数据填充到同一个Partition中,由于在Fore-End呈现的报表大多数是基于Mon ...

  8. 用Spring.Services整合 thrift0.9.2生成的wcf中间代码-复杂的架构带来简单的代码和高可维护性

    最近一直在看关于thrift的相关文章,涉及到的内容的基本都是表层的.一旦具体要用到实际的项目中的时候就会遇到各种问题了! 比如说:thrift 的服务器端载体的选择.中间代码的生成options(a ...

  9. PAT甲题题解-1103. Integer Factorization (30)-(dfs)

    该题还不错~. 题意:给定N.K.P,使得可以分解成N = n1^P + … nk^P的形式,如果可以,输出sum(ni)最大的划分,如果sum一样,输出序列较大的那个.否则输出Impossible. ...

  10. 第二阶段Sprint9

    昨天:重新规划主界面,把视频录制暂放到主页面里 今天:查看有关“共享平台”的资料,看如何实现上传下载功能,并尝试编码, 遇到的问题:看不懂什么意思,照例子做不行,还得需要联网等