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;
}
相关文章
|
测试技术 Android开发 iOS开发
05-iOS自动化常用命令
05-iOS自动化常用命令
|
搜索推荐 数据挖掘 大数据
数据具有无限性、易复制性、非均质性、易腐性和原始性五大特征
数据具有无限性、易复制性、非均质性、易腐性和原始性五大特征
1730 1
|
存储 PyTorch 算法框架/工具
Transformers 4.37 中文文档(三十六)(2)
Transformers 4.37 中文文档(三十六)
190 0
|
缓存 网络协议 算法
【网络基础】TCP协议之三次握手&四次挥手--详解与常见问题解答(下)
【网络基础】TCP协议之三次握手&四次挥手--详解与常见问题解答(下)
11、深入理解计算机系统笔记:存储器层次结构,利用局部性
1、缓存友好的代码 对局部变量的反复引用是好的,因为编译器能够将它们缓存在寄存器文件中(时间局部性)。(内部循环) 步长为1的引用模式是好的,因为存储器层次结构中所有层次上的缓存都是将数据存储为连续的块(空间局部性)。
1076 0
|
3天前
|
存储 弹性计算 缓存
阿里云服务器租赁费用:新版租赁收费标准及活动报价参考
本文更新了2026年阿里云全系列云服务器租赁活动报价,所有特惠资源均可前往阿里云活动中心选购,整体覆盖从个人入门到企业级高性能场景的全梯度需求。其中轻量应用服务器主打极致性价比,2核2G峰值200M带宽配置每日10点、15点限时抢购价仅38元/年,2核4G配置379元/年起;高性价比的经济型e实例、通用算力型u2i实例覆盖2核4G至4核32G全档位,适配开发测试与中小型企业业务;搭载英特尔至强6处理器的第九代c9i企业级实例算力较上代提升20%,支撑高并发生产环境,不同实例规格价差清晰,用户可根据自身业务负载与预算灵活选型。
1407 109
|
10天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1931 8
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
4天前
|
编解码 人工智能 安全
2核4G/4核8G/8核16G阿里云服务器如何选择实例?经济型e、通用算力型u2i与计算型c9i选哪个?
本文介绍了阿里云2核4G、4核8G、8核16G三档主流配置下经济型e、通用算力型u2i和计算型c9i三种实例的最新活动价格与适用场景。同配置下三者价差显著,以2核4G为例,经济型e低至599.93元/年,计算型c9i则高达1742.08元/年。文章详细解析了各实例的性能定位:经济型e适合轻负载入门场景,u2i兼顾稳定算力与性价比,c9i凭借第9代至强处理器与芯片级安全能力支撑高性能业务。同时提示用户可叠加满减优惠券享受折上折,建议根据业务负载与预算综合决策。
513 112
|
4天前
|
人工智能 程序员 API
Codex 接入 DeepSeek-V4-Flash:还能补上识图,提供两套方案
Codex 接入 DeepSeek-V4-Flash 怎么配?本文覆盖 CLI 与桌面端,再用 qwen3-vl-flash 补识图,两套方案可直接照做

热门文章

最新文章