[BZOJ4032] [HEOI2015] 最短不公共子串 - 后缀自动机,序列自动机,BFS
来源:互联网 发布:模拟核弹爆炸软件 编辑:程序博客网 时间:2024/06/08 12:46
4032: [HEOI2015]最短不公共子串
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 398 Solved: 189
[Submit][Status][Discuss]
Description
在虐各种最长公共子串、子序列的题虐的不耐烦了之后,你决定反其道而行之。
一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是。
一个串的“子序列”指的是它的可以不连续的一段,例如bde是abcdef的子串,但bdd不是。
下面,给两个小写字母串A,B,请你计算:
(1) A的一个最短的子串,它不是B的子串
(2) A的一个最短的子串,它不是B的子序列
(3) A的一个最短的子序列,它不是B的子串
(4) A的一个最短的子序列,它不是B的子序列
Input
有两行,每行一个小写字母组成的字符串,分别代表A和B。
Output
输出4行,每行一个整数,表示以上4个问题的答案的长度。如果没有符合要求的答案,输出-1.
Sample Input
aabbcc
abcabc
abcabc
Sample Output
2
4
2
4
4
2
4
HINT
对于100%的数据,A和B的长度都不超过2000
Source
HOME Back
其实序列自动机就是一个纸张的能遍历出所有子序列的自动机。。其实就是每个点的右边的不同字符的最近出现位置。
那么我们这些询问怎么做呢,首先我们建出每个串的后缀自动机和序列自动机,这样我们就能遍历所有的子序列了。
然后这样第一个询问随便用两个后缀自动机来BFS一下就好了(最简单的询问,trie或者hash都可以)。
那么第二个询问怎么搞呢,这个时候我们就发现一个显然对于4个询问都承认的限制:若用dp[i][j]表示第一个串在自动机上匹配到i位置,第二个串在自动机上匹配到j位置,那么显然dp[i][j]最小。
所以我们只要BFS就可以满足这样的要求。我们对于第二个询问匹配第一个串的后缀自动机(遍历所有子串)和序列自动机(遍历所有子序列),同理我们匹配不同的自动机,可以解决这个问题。
时间复杂度O(n^2*26)
#include"bits/stdc++.h"#define F(i,l,r) for(int i=l;i<=r;i++)#define D(i,r,l) for(int i=r;i>=l;i--)using namespace std;const int N=2005,M=26;char s1[N],s2[N];struct SequenceAutoMaton{int a[N],e[N][M],n,last[M];void pre(char*s){n=strlen(s+1);D(i,n,1){memcpy(e[i+1],last,sizeof(int[M]));a[i]=s[i]-'a';last[a[i]]=i+1;}memcpy(e[1],last,sizeof(int[M]));}} sqa[2];struct SuffixAutoMaton{int a[N*2],e[N*2][M],fail[N*2],d[N*2],last,n,nd;SuffixAutoMaton(){nd=last=1;}void extend(int c){int np=++nd,p=last;d[np]=d[last]+1;for(;!e[p][c]&&p;e[p][c]=np,p=fail[p]);if(!p)fail[np]=1;else {int q=e[p][c],nq;if(d[q]==d[p]+1)fail[np]=q;else {nq=++nd;d[nq]=d[p]+1;memcpy(e[nq],e[q],sizeof(int[M]));fail[nq]=fail[q];fail[np]=fail[q]=nq;for(;e[p][c]==q;e[p][c]=nq,p=fail[p]);}}last=np;}void pre(char*s){n=strlen(s+1);F(i,1,n){a[i]=s[i]-'a';extend(a[i]);}}} sam[2];int dp[2*N][2*N],q1[N*N],q2[N*N],l,r;template<class T1,class T2>void DP(T1&x,T2&y){q1[1]=q2[1]=1;memset(dp,0,sizeof(dp));for(l=r=1;l<=r;l++){F(i,0,25){int dx=x.e[q1[l]][i],dy=y.e[q2[l]][i];if(!dx)continue;if(!dy){printf("%d\n",dp[q1[l]][q2[l]]+1);return;}if(dp[dx][dy])continue;dp[dx][dy]=dp[q1[l]][q2[l]]+1;++r;q1[r]=dx;q2[r]=dy;}}puts("-1");}int main(){scanf("%s\n%s",s1+1,s2+1);sqa[0].pre(s1),sqa[1].pre(s2);sam[0].pre(s1),sam[1].pre(s2);DP(sam[0],sam[1]);DP(sam[0],sqa[1]);DP(sqa[0],sam[1]);DP(sqa[0],sqa[1]); return 0;}
0 0
- [BZOJ4032] [HEOI2015] 最短不公共子串 - 后缀自动机,序列自动机,BFS
- 【BZOJ4032】【HEOI2015】最短不公共子串 后缀自动机
- BZOJ 4032 HEOI2015 最短不公共子串 后缀自动机+序列自动机+BFS
- bzoj 4032: [HEOI2015]最短不公共子串 后缀自动机+序列自动机+bfs+记忆化搜索
- bzoj4032: [HEOI2015]最短不公共子串
- 【HEOI2015】【BZOJ4032】最短不公共子串
- BZOJ4032: [HEOI2015]最短不公共子串
- bzoj 4032: [HEOI2015]最短不公共子串 (DP+后缀自动机)
- BZOJ4032【后缀自动机】【序列自动机】
- bzoj 4032 [HEOI2015]最短不公共子串 后缀trie
- 4032: [HEOI2015]最短不公共子串
- bzoj 4032 [HEOI2015]最短不公共子串
- 后缀自动机
- 后缀自动机
- 后缀自动机
- 后缀自动机
- 后缀自动机)
- 后缀自动机
- VR测试视频源,双目立体视觉测试视频,大分辨率2880x1440-25fps
- Material Design之CollapsingToolbarLayout使用
- 设置字体
- 如何用视频编辑软件让彩色突出
- LeetCode------11. Container With Most Water
- [BZOJ4032] [HEOI2015] 最短不公共子串 - 后缀自动机,序列自动机,BFS
- Android 窗口管理服务WindowManagerService 简介
- python中tile()函数
- Codeforces Round #372 (Div. 1) A. Plus and Square Root 解题报告
- android SD卡浏览器
- 试题:基本算法题之【计算买股票的第n天每股股票值多少钱】
- 欢迎使用CSDN-markdown编辑器
- hdu--5878(hdu 5878 I Count Two Three (2016 ACM/ICPC Asia Regional Qingdao Online 1001))
- 名厨android2.0项目总结