【学习笔记】[AGC037F] Counting of Subarrays
将递归反着做,每次相当于选择长度 ≥ L ′ \ge L' ≥L′的连续段 x x x删除,替换成 x + 1 x+1 x+1。
对于区间 [ l : r ] [l:r] [l:r]可能属于多个级别,考虑将其定义为最小的级别,即区间最大值 + 1 +1 +1。
那么我们考虑怎么统计答案。记 [ l : r ] [l:r] [l:r]的最大值为 k k k,那么当 < k <k <k的段都被合并后,若 [ l : r ] [l:r] [l:r]对应的串的长度 ≥ L ′ \ge L' ≥L′,那么对答案会有贡献。
如果暴力做我们就用 [ l , r , i ] [l,r,i] [l,r,i]表示区间 [ l : r ] [l:r] [l:r]的连续段 i i i,每次把 i i i对应的区间并起来,再合并到 i + 1 i+1 i+1去,注意这里我们要用 set \text{set} set存储,我们不加证明的指出复杂度为 O ( n log n ) O(n\log n) O(nlogn)。
接下来的做法我是想不到的 我们考虑将问题进行泛化,每个点有
L
i
,
R
i
L_i,R_i
Li,Ri,合法区间
[
l
:
r
]
[l:r]
[l:r]的贡献是
L
l
R
r
L_lR_r
LlRr。
如何将泛化后的问题应用到原序列上?注意到:
1.1
1.1
1.1 对于一个连续段,贡献是
∑
r
−
l
≥
L
L
l
R
r
\sum_{r-l\ge L}L_lR_r
∑r−l≥LLlRr,可以
O
(
l
e
n
)
O(len)
O(len)计算
1.2
1.2
1.2 如果我们将长度为
m
m
m的
k
k
k合并成
⌊
m
L
′
⌋
\lfloor\frac{m}{L'}\rfloor
⌊L′m⌋个
k
+
1
k+1
k+1,相当于一个点代表原序列的一段,那么如果
[
l
,
r
]
⊆
[
L
,
R
]
[l,r]\subseteq[L,R]
[l,r]⊆[L,R],这样的代替是正确的,因为
[
L
,
R
]
[L,R]
[L,R]包含了将
[
l
,
r
]
[l,r]
[l,r]合并时的结果。如果
[
L
,
R
]
⊆
[
l
,
r
]
[L,R]\subseteq [l,r]
[L,R]⊆[l,r]那么我们已经在上一步计算过方案了,我们只需考虑一个端点落在
[
l
,
r
]
[l,r]
[l,r]的情况。假设
L
∈
[
l
,
r
]
L\in [l,r]
L∈[l,r],那么首先会合并
[
L
,
r
]
[L,r]
[L,r],此时会生成
⌊
r
−
L
+
1
L
′
⌋
\lfloor\frac{r-L+1}{L'}\rfloor
⌊L′r−L+1⌋段,我们找到对应位置累加即可。
复杂度 O ( n log n ) O(n\log n) O(nlogn)。实现比较复杂,可以考虑用链表删除元素,用堆每次找到最小的那一段。
__EOF__

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