[POJ3415]Common Substrings(后缀数组+单调栈)

该博客详细介绍了如何利用后缀数组和单调栈来解决寻找两个字符串中长度不小于k的公共子串个数的问题。通过将一串接在另一串后面并插入特殊字符,构建后缀数组和高度数组,然后按高度分组。通过两遍扫描,结合单调栈统计符合条件的子串数量,避免了暴力求解的复杂度,实现了更优的算法解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

传送门
题意:给定两个字符串 A 和 B ,求长度不小于 k 的公共子串的个数(可以相同)。

题解

首先把一个串接在另一个串的后面,中间放一个没出现过的字符。
由于每一个子串都是某一个后缀的前缀,求出sa和height了之后,我们可以将height分组,组内都是height>=k的后缀。可以知道长度不小于k的公共子串是两个后缀的前缀,并且它们一定在同一组内
那么对于每一组,从前往后扫,假设遇到了A的后缀,那么统计一下它前面与B的后缀能组成多少>=k的公共子串,然后再把A和B反一下,这样扫两遍,就求出了答案。
关键是怎么统计。暴力统计是 O(n2) 的肯定不行。我们知道两个后缀的最长公共前缀是它们的区间最小值,所以可以维护一个自底向上单调递增的栈。同时需要维护的是,栈中的总和已经栈中每一个元素的出现次数。需要注意的是,只有需要统计的一种后缀的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值