CodeForces 427D Match & Catch 后缀数组

简介: CodeForces 427D Match & Catch 后缀数组

Police headquarter is monitoring signal on different frequency levels. They have got two suspiciously encoded strings s1 and s2 from two different frequencies as signals. They are suspecting that these two strings are from two different criminals and they are planning to do some evil task.


Now they are trying to find a common substring of minimum length between these two strings. The substring must occur only once in the first string, and also it must occur only once in the second string.


Given two strings s1 and s2 consist of lowercase Latin letters, find the smallest (by length) common substring p of both s1 and s2, where p is a unique substring in s1 and also in s2. See notes for formal definition of substring and uniqueness.


Input

The first line of input contains s1 and the second line contains s2 (1 ≤ |s1|, |s2| ≤ 5000). Both strings consist of lowercase Latin letters.


Output

Print the length of the smallest common unique substring of s1 and s2. If there are no common unique substrings of s1 and s2 print -1.

题目大意:

就是对于两个字符串s1和s2, 求出他们最短的一个公共字串t,满足t在s1中只出现1次, t在s2中也只出现一次, 输出t最小的长度, 如果这样的t不存在, 输出-1


思路:将这两个字符串拼成一个串,中间用一个没出现过的字符隔开(我用的空格),对合成的串求后缀数组,这样两个数组的公共子串所在的后缀在sa中应该是相邻的。通过观察,只有当这两个sa中相邻的后缀sa[i]和sa[i-1]左右的后缀都不含这个子串时,才能保证子串在两个串都只出现一次。


具体来说就是

(1)后缀sa[i]和sa[i-1]分别属于两个字符串

(2)height[i-1] < height[i] && height[i+1] < height[i]

(3)这个最小公共子串长度就是max(height[i-1], height[i+1]) + 1


整体扫过一遍height数组统计最小值即可,没有满足的情况时输出-1

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 2e6 + 5;
char s1[maxn], s2[maxn], s[maxn];
int n, p1, p2, m, p;
int tx[maxn], sa[maxn], rak[maxn];
int height[maxn], num1[maxn];
const int inf = 1e9;
struct node {
  int x, y, id;
}a[maxn], b[maxn];
void rsort() {
  for (int i = 1; i <= m; i++) {
    tx[i] = 0;
  }
  for (int i = 1; i <= n; i++) {
    tx[a[i].y]++;
  }
  for (int i = 1; i <= m; i++) {
    tx[i] += tx[i - 1];
  }
  for (int i = 1; i <= n; i++) {
    b[tx[a[i].y]--] = a[i];
  }
  for (int i = 1; i <= m; i++) {
    tx[i] = 0;
  }
  for (int i = 1; i <= n; i++) {
    tx[b[i].x]++;
  }
  for (int i = 1; i <= m; i++) {
    tx[i] += tx[i - 1];
  }
  for (int i = n; i >= 1; i--) {
    a[tx[b[i].x]--] = b[i];
  }
}
void solve() {
  rsort();
  p = 0;
  for (int i = 1; i <= n; i++) {
    if (a[i].x == a[i - 1].x && a[i].y == a[i - 1].y) {
      rak[a[i].id] = p;
    } else {
      rak[a[i].id] = ++p;
    }
  }
  for (int i = 1; i <= n; i++) {
    a[i].x = rak[i];
    a[i].id = sa[rak[i]] = i;
    a[i].y = 0;
  }
  m = p;
}
void ssort() {
  m = 127;
  for (int i = 1; i <= n; i++) {
    a[i].x = a[i].y = s[i];
    a[i].id = i;
  }
  solve();
  for (int j = 1; j <= n; j <<= 1) {
    for (int i = 1; i + j <= n; i++) {
      a[i].y = a[i + j].x;
    }
    solve();
    if (p == n) {
      break;
    }
  }
} 
void get_Height() {
  int k = 0;
  for (int i = 1; i <= n; i++) {
    if (k) {
      k--;
    }
    int j = sa[rak[i] - 1];
    while (s[i + k] == s[j + k]) {
      k++;
    }
    height[rak[i]] = k;
  }
}
int main() {
  scanf("%s", s1 + 1);
  scanf("%s", s2 + 1);
  p1 = strlen(s1 + 1);
  p2 = strlen(s2 + 1);
  for (int i = 1; i <= p1; i++) {
    s[++n] = s1[i];
    num1[n] = 2;
  }
  s[++n] = '#';
  for (int i = 1; i <= p2; i++) {
    s[++n] = s2[i];
    num1[n] = 1;
  }
  ssort();
  get_Height();
  int ans = inf;
  for (int i = 2; i <= n; i++) {
      if (num1[sa[i]] + num1[sa[i - 1]] == 3 && height[i - 1] < height[i] && height[i] > height[i + 1]) {
        ans = min(ans, max(height[i - 1], height[i + 1]) + 1);
    }
  }
  printf("%d\n", ans == inf ? -1 : ans);
  return 0;
}
相关文章
|
API
vite.config.js 的一些常用配置
vite.config.js 的一些常用配置
893 1
|
安全 网络安全 数据安全/隐私保护
【计算机网络】URL概念及组成
【计算机网络】URL概念及组成
|
JSON JavaScript 数据格式
Elementui Tree 树形控件删除子节点
Elementui Tree 树形控件删除子节点
435 1
|
11月前
|
SQL Oracle 关系型数据库
担心YashanDB异构数据库迁移踩“坑”?听听大咖们怎么说
文章围绕异构数据库迁移展开,探讨了避免数据丢失、保障数据完整性、注意兼容性、提升迁移效率、做好反向演练等问题。包括迁移前完整性检查与备份,YashanDB 从内核设计和配套工具保障数据,对兼容性进行大量测试,通过合理评估和技术手段提升迁移效率,以及处理回退等内容。
|
编译器 C语言 计算机视觉
C语言实现的图像处理程序
C语言实现的图像处理程序
|
12月前
|
存储 前端开发 开发工具
利用阿里云OSS(对象存储服务)快速搭建私人网盘
本文介绍了如何使用阿里云OSS搭建个人网盘的详细步骤。首先,注册阿里云账号并开通OSS服务,创建Bucket;接着,配置AccessKey和跨域访问(CORS)规则。然后,选择开源项目(如FileBrowser)或自定义前端,结合OSS SDK实现文件上传下载功能。最后,部署到服务器并绑定域名,确保安全与性能优化,如权限控制、数据备份及CDN加速。
2864 7
|
自然语言处理 搜索推荐 数据安全/隐私保护
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
鸿蒙登录页面设计展示了 HarmonyOS 5.0(Next)的未来美学理念,结合科技与艺术,为用户带来视觉盛宴。该页面使用 ArkTS 开发,支持个性化定制和无缝智能设备连接。代码解析涵盖了声明式 UI、状态管理、事件处理及路由导航等关键概念,帮助开发者快速上手 HarmonyOS 应用开发。通过这段代码,开发者可以了解如何构建交互式界面并实现跨设备协同工作,推动智能生态的发展。
778 10
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
|
机器学习/深度学习 人工智能 前端开发
2024年软件开发新趋势:关键技术和实践
2024年软件开发迎来新趋势,涵盖AI/ML深度集成、微前端架构进展、单元测试最佳实践及CI/CD最新动态,推动产品质量、效率和创新的提升。
|
监控 安全 Go
使用Golang调用摄像头
近年来,摄像头成为了我们生活中不可或缺的设备之一。从智能手机到安全监控系统,无处不在的摄像头给我们带来了便利和安全。在开发摄像头相关的应用程序时,选择一种高效和易用的编程语言是非常重要的。本文将介绍如何使用Golang调用摄像头并进行图像处理。
|
C语言 Windows
C语言中的fopen与fclose函数详解
C语言中的fopen与fclose函数详解
1125 28