【题解】「AHOI2013」 差异
题目描述
给定一个长度为
n
n
n 的字符串
S
S
S,令
T
i
T_i
Ti 表示它从第
i
i
i 个字符开始的后缀。求
∑
1
<
=
i
<
j
<
=
n
n
l
e
n
(
T
i
)
+
l
e
n
(
T
j
)
−
2
×
l
c
p
(
T
i
,
T
j
)
\sum_{1<=i<j<=n}^{n}len(Ti)+len(Tj)−2×lcp(Ti,Tj)
1<=i<j<=n∑nlen(Ti)+len(Tj)−2×lcp(Ti,Tj)
solution:
主要是一个单调栈+后缀数组模板的运用。发现每个区间的值就是这个区间的最小值,而区间的最小值一般用单调栈来维护。
本人不是很会维护单调栈,所以当时找到了两种比较好的维护方法自己的wa了。
法一.
由于是正序枚举,且是区间最小,所以若i<j,且height[i]>height[j],那么j后面的位置一定不会以height[i]作为高度,因为j更近,只要i能成为候选答案,j就会成为最优的答案。对于后面的点来说,只需满足j即可,所以i是冗余的,应该将i弹出。
所以这个单调栈一定是单调递增的。
我们考虑将右端点固定下来。设 f [ j ] f[j] f[j]表示以 j j j结尾的区间的贡献和。
那么我们怎么把
f
[
j
]
f[j]
f[j]求出来呢?这个时候就要转移了:
f
[
i
]
=
f
[
p
]
+
(
i
−
p
)
∗
h
[
i
]
(
h
[
p
]
<
h
[
i
]
∣
p
<
i
)
f[i]=f[p]+(i-p)*h[i](h[p]<h[i] | p<i)
f[i]=f[p]+(i−p)∗h[i](h[p]<h[i]∣p<i)
注意是否严格递增都是对的。
法二.
这个思路要抽象一些。
首先还是维护单调递增的栈。这里必须是不严格递增。
令L[i]表示i往左边最多扩展的位置,R[i]表示i往右边最多扩展的位置,则点i的贡献为 ( i − L [ i ] ) ∗ ( R [ i ] − i ) ∗ h e i g h t [ i ] (i-L[i])*(R[i]-i)*height[i] (i−L[i])∗(R[i]−i)∗height[i]
为什么是正确的呢?假如i与相邻的数不同,那么以h[i]扩展出来的左右端点一定不会重复。如果左右相等,我们仔细观察下面代码,发现L[i]=i(除了这段连续的数中最左边的数有可能往左拓展以外),而右端点都是相同的。此时我们可以发现恰好把每种可能的左端点都枚举了一遍,且没有重复。
总结:首先,我们根据区间最小值进行分类,分别计算答案。其次,我们不允许它向和它相等且在它前面的数扩展,有效避免了重复。
于是就解决了。
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530370.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」