洛谷 P4112 [HEOI2015]最短不公共子串 解题报告
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]最短不公共子串 解题报告的更多相关文章
- BZOJ 4032 Luogu P4112 [HEOI2015]最短不公共子串 (DP、后缀自动机)
		这其实是道水题... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4032 (luogu)https://www.luog ... 
- 【BZOJ4032】[HEOI2015]最短不公共子串(后缀自动机,序列自动机)
		[BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\) ... 
- BZOJ 4032: [HEOI2015]最短不公共子串
		4032: [HEOI2015]最短不公共子串 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 446 Solved: 224[Submit][Sta ... 
- BZOJ 4032: [HEOI2015]最短不公共子串 后缀自动机 暴力
		4032: [HEOI2015]最短不公共子串 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4032 Description 在虐各种最 ... 
- bzoj4032: [HEOI2015]最短不公共子串(SAM+DP)
		4032: [HEOI2015]最短不公共子串 题目:传送门 题解: 陈年老题良心%你赛膜爆嘎爷 当初做题...一眼SAM...结果只会两种直接DP的情况... 情况1: 直接设f[i][j] 表示的 ... 
- luoguP4112 [HEOI2015]最短不公共子串 SAM,序列自动机,广搜BFS
		luoguP4112 [HEOI2015]最短不公共子串 链接 luogu loj 思路 子串可以用后缀自动机,子序列可以用序列自动机. 序列自动机是啥,就是能访问到所有子序列的自动机. 每个点记录下 ... 
- bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)
		bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ... 
- BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心
		题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ... 
- BZOJ4032:[HEOI2015]最短不公共子串(SAM)
		Description 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列” ... 
随机推荐
- [NOI2003]Editor & [AHOI2006]文本编辑器editor BZOJ1507&BZOJ1269
			分析: Splay区间操作裸题,维护出区间信息,按照要求模拟,注意读入格式,并且考虑内存回收(开不下) 附上代码: #include <cstdio> #include <algor ... 
- Luogu  P2577 [ZJOI2005]午餐
			一道贪心+类背包DP的好题 首先发现一个十分显然的性质,没有这个性质整道题目都难以下手: 无论两队的顺序如何,总是让吃饭慢的人先排队 这是一个很显然的贪心,因为如果让吃饭慢的排在后面要更多的时间至少没 ... 
- 【转载】VS配置路径和宏
			原文路径:http://blog.csdn.net/puttytree/article/details/7838419 在介绍项目配置之前,先说明两点 1. 项目配置中,最好不要使用相对路径,更不要使 ... 
- PowerBI开发 第五篇:关系和交互
			PowerBI 使用 内存的列式数据库 VertiPaq,用于对已发布的数据集进行数据压缩和快速处理,能够使PowerBI报表执行脱机访问,面向列的处理,高度优化对1:N关系的处理性能.关系是数据分析 ... 
- 利用JS实现一个简单的二级联动菜单
			前几天在看js的相关内容,所以就简单写了一个二级联动菜单.分享一下. <!DOCTYPE html> <html lang="en"> <head&g ... 
- C#_Winfrom将浏览器生成Image
			using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ... 
- Js_闭包跟作用域
			作用域的嵌套将形成作用域链,函数的嵌套将形成闭包.闭包与作用域链是 JavaScript 区别于其它语言的重要特性之一. 作用域 JavaScript 中有两种作用域:函数作用域和全局作用域. 在一个 ... 
- 验证Xpath和CSS 路径是否有效
			XPath定位和CSS定位在Selenium中是经常使用的. 在FireFox浏览器和Chrome浏览器,可以使用这样的方法来验证定位是否准确. 以Chrome浏览器做范例 按键盘的F12 进入开发者 ... 
- GitHub 新手教程 三,Git Bash
			1,通过 开始菜单 启动 Git Bash,或者 在 cmd 下执行以下命令: D:\SoftWare\Git\git-bash.exe --cd-to-home (D:\SoftWare\Git 是 ... 
- unity纯粹物理驱动方式
			首先见官方文档 In most cases you should not modify the velocity directly, as this can result in unrealistic ... 
