博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ4032 [HEOI2015]最短不公共子串
阅读量:6590 次
发布时间:2019-06-24

本文共 3140 字,大约阅读时间需要 10 分钟。

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

Sample Output

2
4
2
4

HINT

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

题解

如果都是子串,那么直接在后缀自动机上BFS即可;否则,可以乱搞出什么“子序列自动机”(只需要把每个节点连到它的下一个a、下一个b、...下一个z即可),然后bfs。

(为了一句last=ne调了一个小时QAQ)

附代码:

#include 
#include
#include
#include
#include
const int N = 4050;struct Node{ int nxt[26], pa, len;};struct Automation{ Node nodes[N]; int cnt; inline int newNode(int l = 0) { memcpy(&nodes[cnt].nxt, &nodes[l].nxt, sizeof(int) * 26); nodes[cnt].pa = nodes[l].pa; nodes[cnt].len = nodes[l].len; return cnt++; } int root; int seq_last[26], last; void init() { memset(&nodes[0], 0, sizeof(Node)); cnt = 1; root = newNode(); for (int i = 0; i < 26; ++i) seq_last[i] = root; last = root; } void seq_append(int x) { int ne = newNode(); for (int i = 0; i < 26; ++i) for (int q = seq_last[i]; q && !nodes[q].nxt[x]; q = nodes[q].pa) nodes[q].nxt[x] = ne; nodes[ne].pa = seq_last[x]; seq_last[x] = ne; } void suffix_append(int x) { int ne = newNode(); nodes[ne].len = nodes[last].len + 1; int q = last; while (q && !nodes[q].nxt[x]) { nodes[q].nxt[x] = ne; q = nodes[q].pa; } if (!q) { nodes[last = ne].pa = root; return; } int p = nodes[q].nxt[x]; if (nodes[p].len == nodes[q].len + 1) { nodes[last = ne].pa = p; return; } int pq = newNode(p); nodes[pq].len = nodes[q].len + 1; nodes[last = ne].pa = nodes[p].pa = pq; while (q && nodes[q].nxt[x] == p) { nodes[q].nxt[x] = pq; q = nodes[q].pa; } }};struct AAA{ int x, y, len; AAA(int a, int b, int c) : x(a), y(b), len(c) {}};std::bitset
vis[N];std::queue
Q;int bfs(const Automation &A, const Automation &B) { while (!Q.empty()) Q.pop(); Q.push(AAA(A.root, B.root, 0)); for (int i = 0; i < A.cnt; ++i) vis[i].reset(); vis[A.root][B.root] = 1; while (!Q.empty()) { AAA x = Q.front(); Q.pop(); const Node &a = A.nodes[x.x], &b = B.nodes[x.y]; for (int i = 0; i < 26; ++i) { int l = a.nxt[i], r = b.nxt[i]; if (!l) continue; if (!r) return x.len + 1; if (!vis[l][r]) Q.push(AAA(l, r, x.len + 1)); vis[l][r] = 1; } } return -1;}Automation a, b;char s[N], p[N];int main() { scanf("%s%s", s, p); a.init(); for (char *r = s; *r; ++r) a.suffix_append(*r - 'a'); b.init(); for (char *r = p; *r; ++r) b.suffix_append(*r - 'a'); printf("%d\n", bfs(a, b)); b.init(); for (char *r = p; *r; ++r) b.seq_append(*r - 'a'); printf("%d\n", bfs(a, b)); a.init(); for (char *r = s; *r; ++r) a.seq_append(*r - 'a'); int ans4 = bfs(a, b); b.init(); for (char *r = p; *r; ++r) b.suffix_append(*r - 'a'); printf("%d\n", bfs(a, b)); printf("%d\n", ans4); return 0;}

  

转载于:https://www.cnblogs.com/y-clever/p/7373033.html

你可能感兴趣的文章
C++ WINDOWS下 wchar_t *和char * 相互转化总结篇
查看>>
LeetCode:Valid Number
查看>>
ASP开发基础
查看>>
mongodb远程连接访问
查看>>
MYSQL性能调优
查看>>
LVM自动扩容
查看>>
笔记整理4
查看>>
森林病虫防治系统 (二.1)
查看>>
延时执行和取消延时执行
查看>>
\045在字符串中输出为%
查看>>
在eclipse中如何搭建ssh框架
查看>>
idea文件折叠显示出来配置
查看>>
垃圾回收解析
查看>>
SQLSERVER中的非工作时间不得插入数据的触发器的实现
查看>>
Java异常以及继承的一些问题
查看>>
如何写出兼容大部分浏览器的CSS 代码
查看>>
asp.net 百度编辑器 UEditor 上传图片 图片上传配置 编辑器配置 网络连接错误,请检查配置后重试...
查看>>
第二阶段冲刺第八天,6月7日。
查看>>
java的左移位(<<)和右移位(>>)和无符号右移(>>>)
查看>>
find -exec 与xargs 区别
查看>>