题目描述

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

一个串的“子串”指的是它的连续的一段,例如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.

输入输出样例

输入样例#1: 复制

aabbcc
abcabc
输出样例#1: 复制

2
4
2
4
输入样例#2: 复制

aabbcc
aabbcc
输出样例#2: 复制

-1
-1
2
-1

说明

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

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

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

题解

  这题好烦……

  据说还有大佬是用dp的方法做的……相当于做了四道题……先膜为敬……

  然后看到有大佬是直接建上后缀自动机和回文自动机,然后在上面跑BFS,如果跑不动了就返回答案,可以保证最优

  然后我因为一堆sb错误调了一个多小时……

  为啥取队头元素不能直接整个结构体取啊!为啥我SAM都能打错啊!

 //minamoto
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=;
struct SAM{
int fa[N],ch[N][],l[N];int last,cnt;
SAM(){last=cnt=;}
void ins(int c){
int p=last,np=++cnt;last=np,l[np]=l[p]+;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=;
else{
int q=ch[p][c];
if(l[q]==l[p]+) fa[np]=q;
else{
int nq=++cnt;l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
}
}SA,SB;
struct SqAM{
int ch[N][],lst[],fa[N];
int root,cnt;
SqAM(){root=cnt=;for(int i=;i<;++i) lst[i]=;}
void ins(int c){
int p=lst[c],np=++cnt;
fa[np]=p;
for(int i=;i<;++i)
for(int j=lst[i];j&&!ch[j][c];j=fa[j])
ch[j][c]=np;
lst[c]=np;
}
}SQA,SQB;
struct node{
int a,b,step;
node(int a=,int b=,int step=):a(a),b(b),step(step){}
};
int vis[N][N];
int bfs1(){
queue<node> q;
q.push(node(,,));
vis[][]=;
while(!q.empty()){
int ra=q.front().a,rb=q.front().b,st=q.front().step;
for(int i=;i<;i++){
int va=SA.ch[ra][i],vb=SB.ch[rb][i];
if(va&&vb){
if(vis[va][vb]==) continue;
q.push(node(va,vb,st+));
vis[va][vb]=;
}
if(va&&!vb) return st+;
}
q.pop();
}
return -;
}
int bfs2(){
queue<node> q;
q.push(node(,,));
vis[][]=;
while(!q.empty()){
int ra=q.front().a,rb=q.front().b,st=q.front().step;
for(int i=;i<;i++){
int va=SA.ch[ra][i],vb=SQB.ch[rb][i];
if(va&&vb){
if(vis[va][vb]==) continue;
q.push(node(va,vb,st+));
vis[va][vb]=;
}
if(va&&!vb) return st+;
}
q.pop();
}
return -;
}
int bfs3(){
queue<node> q;
q.push(node(,,));
vis[][]=;
while(!q.empty()){
int ra=q.front().a,rb=q.front().b,st=q.front().step;
for(int i=;i<;i++){
int va=SQA.ch[ra][i],vb=SB.ch[rb][i];
if(va&&vb){
if(vis[va][vb]==) continue;
q.push(node(va,vb,st+));
vis[va][vb]=;
}
if(va&&!vb) return st+;
}
q.pop();
}
return -;
}
int bfs4(){
queue<node> q;
q.push(node(,,));
vis[][]=;
while(!q.empty()){
int ra=q.front().a,rb=q.front().b,st=q.front().step;
for(int i=;i<;i++){
int va=SQA.ch[ra][i],vb=SQB.ch[rb][i];
if(va&&vb){
if(vis[va][vb]==) continue;
q.push(node(va,vb,st+));
vis[va][vb]=;
}
if(va&&!vb) return st+;
}
q.pop();
}
return -;
}
char a[N],b[N];int tot1,tot2;char ch;
int main(){
scanf("%s%s",a+,b+);
tot1=strlen(a+),tot2=strlen(b+);
for(int i=;i<=tot1;++i) SA.ins(a[i]-'a'),SQA.ins(a[i]-'a');
for(int i=;i<=tot2;++i) SB.ins(b[i]-'a'),SQB.ins(b[i]-'a');
printf("%d\n%d\n%d\n%d\n",bfs1(),bfs2(),bfs3(),bfs4());
return ;
}

BZOJ4032: [HEOI2015]最短不公共子串(后缀自动机+序列自动机)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Java中Final修饰一个变量时,是引用不能变还是引用的对象不能变

    Java中,使用Final修饰一个变量,是引用不能变,还是引用对象不能变? 是引用对象的地址不能变,引用变量所指的对象的内容可以改变. final变量永远指向这个对象,是一个常量指针,而不是指向常量的 ...

  2. go grpc

    https://godoc.org/google.golang.org/grpc go get google.golang.org/grpc go get -a github.com/golang/p ...

  3. 微信小程序相关二、css介绍,菜单制作,表单相关,京东注册页面

    一.第二天上午 1.1上午因为有其他的课所以没有去这个课,不过下午看复习的时候的概括,讲了DTD,语法特性,css选择器以及权重,还有一些简单的样式 1.2 DTD Docuement Type 声明 ...

  4. 高德地图-android 权限设置

    转自http://blog.csdn.NET/eyu8874521/article/details/8481953 一个Android应用程序需要权限才能调用某些android系统的功能:一个andr ...

  5. Ubuntu Server 12.04 LTS搭建SVN服务及修改端口

    采用了apache结合svn的方式. 首先安装apache.subversion.svn-apache sudo apt-get install apache2 sudo apt-get instal ...

  6. BMP结构详解

    位图BITMAPINFOHEADER 与BITMAPFILEHEADER: 先来看BITMAPINFOHEADER,只写几个主要的biSize包含的是这个结构体的大小(包括颜色表)    biWidt ...

  7. adf错误

    1>无法验证事务处理中的所有行 运行项目报错: javax.faces.el.EvaluationException: oracle.jbo.TxnValException: JBO-27023 ...

  8. porwedesigner 去掉引号

    PowerDesigner生成的ORACLE 建表脚本中去掉对象的双引号,设置大.小写 若要将 CDM 中将 Entity的标识符都设为指定的大小写,则可以这么设定: 打开cdm的情况下,进入Tool ...

  9. 协方差与pearson相关系数

    协方差 协方差大于0,表示两个随机变量正线性相关 协方差等于0,表示两随机变量无线性相关 协方差小于0,表示两随机变量负线性相关 协方差智能表示随机变量的线性相关关系,不能刻画其相关程度. 因此引入了 ...

  10. 【原创】cython and python for kenlm

    未经允许不可转载 Kenlm相关知识 Kenlm下载地址 kenlm中文版本训练语言模型 如何使用kenlm训练出来的模型C++版本 关于Kenlm模块的使用及C++源码说明 加载Kenlm模块命令 ...