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 $ ,请你计算: ...
随机推荐
- web 端即时通讯
1. 前言 Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Serve ...
- C - Queue at the School
Problem description During the break the schoolchildren, boys and girls, formed a queue of n people ...
- C# 常用代码片段
一.从控制台读取东西代码片断: using System; class TestReadConsole { public static void Main() { Console.Write(Ente ...
- First step in troubleshooting complex issues: Define and scope your issue properly
最近在查调试相关资料的时候,无意看到Tess的一篇关于如何快速分析复合场景问题的博文,感觉很实用,Mark备忘. My 9 questions for a pretty thorough proble ...
- Android Studio复制项目 两个App之间不覆盖安装操作步骤
步骤一:修改包名 第五步注意:不能以数字等作为包名的开头. 步骤二:修改清单文件里面的包名 第八步注意:如果报红,从新引入新的包名下的Mainactivity类. 步骤三:修改Gradle Scrip ...
- Websphere 手动模拟删除应用操作
Websphere 手动模拟删除应用操作 切记:不要在程序还在运行的时候,直接的remove掉应用程序,不然,会发生意外的错误. 最近,在项目中,不小心手动移除了正在运行的应用,发现se ...
- Self-hosting Sentry With Docker and Docker-compose
If a user encounters an error but you don't know about, did it happen at all? Sentry is one of the s ...
- Centos 7 安装图形化界面
Centos 7 默认是没有图形化界面的,但我们很多人在习惯了 Windows 的图形化界面之后,总是希望有一个图形化界面从而方便我们使用,这里介绍一下 CentOS7安装图形化桌面系统的方法. 一. ...
- JS 样式叠加显示
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 关于MySQL日期操作函数 date_formate 的使用
基本语法:DATE_FORMAT(date,format)说明:date 参数是合法的日期.format 规定日期/时间的输出格式.可以用的格式主要有格式 描述%a 缩写星期名%b 缩写月名%c 月, ...