【总结】倍增
前言:本人发现做倍增的题完全是无从下手,所以补了之前两道倍增的题,现来讲讲思路。
专题:用倍增优化前缀pre数组(类似于lca)
A.城市网络
分析:这道题没想到思路就很难做。
首先是一个树上倍增,这很明显。
思路一: f [ x ] [ y ] f[x][y] f[x][y]表示 x x x到 x x x的 2 y 2^y 2y祖先的路径中的最大值。只要c>=f[x][y],就跳 2 y 2^y 2y步。直到不能跳为止,这个时候令ans++,x=fa[x].这样虽然能跳过不交易的点,但是假如每一个点都要交易,就与暴力无异了。
思路二:
f
[
x
]
[
y
]
f[x][y]
f[x][y]表示
x
x
x第
2
y
2^y
2y交易后的位置。这里初始价值为cost[x]。不难发现具有传递性,所以:
f
[
y
]
[
j
]
=
f
[
f
[
y
]
[
j
−
1
]
]
[
j
−
1
]
f[y][j]=f[f[y][j-1]][j-1]
f[y][j]=f[f[y][j−1]][j−1]
再写一个find函数,用于求对于任意价值y,从节点x开始,第一个cost[z]>y的点z。然后就可以利用上述f数组求解。注意用dep[]数组存深度,这是有根树的bfs的基本操作,就不讲了。时间复杂度O(nlogn)
B.国旗计划
本题思路比较杂,是一个环形的区间覆盖问题,而且要解决多个初始点。但主要分为4步:
- 环破链。对枚举的初始区间[l,r],可看作覆盖区间[l,l+m]。而[l,r]会多分裂出来一个区间[l+m,r+m],用于第二圈使用。
- 预处理f[i][0]。换句话说,就是对于每个给定的区间[l,r],求出一个后继[L,R],使l<=L<=r&&R最大。可以先按l排序,这样r也是单调递增的(因为没有包含关系),这样从1到cnt,发现i会继承1-i-1的所有决策区间,所以j和idx不用重新赋值。时间复杂度降为O(n)
- 求出f[][]数组。直接用倍增板子。
- 根据f[][]数组计算,若s[p].r超出了s[i].l+m,则说明跳大了。最后输出ans+1(因为最后还要选择一个区间,才能到达s[i].l+m,倍增跳的是没到达部分)。
总时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn).
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530400.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 热点速览」