AtCoder Beginner Contest 250 G,H
G
法1:
我们有一种显然的贪心思路——对于一个,尝试找到后面一个,满足,在时刻买入,在时刻卖出。
这样的做法显然不对。
假设我们是在时买入一个stonk,在时卖出,而在时卖出是最优解。那么我们可以假设在时刻卖出后,我们立刻以的价格“尝试”买入,然后在时刻,发现前面有时刻的stonk,则总价值为,那么和时买入时卖出是没有差异的。
我们使用堆去维护,对于从到,我们找到堆中最小的元素,如果它小于,那么我们暂且卖出它,并将加入队列中。最后,我们还需要把本身加入。
法2:
假设表示我们在时刻买入stonk,表示我们在时刻卖出stonk,表示我们什么都不做。
那么我们的前缀和必须要满足。
开始我们假设所有点都是。
从大往小考虑:若我们选择在时刻卖出,那么都要减去;若我们在时刻什么都不做,那么都要减去;否则维持原样,也不改变。
我们肯定尽可能将更多的点改为,其次是。所以对于时,我们肯定选择在时刻卖出;对于时,我们选择什么都不做;否则我们选择维持原样。
这可以使用线段树实现。
H
注意到出发和到达点都是house,那么我们大致的路线就是从出发,到达另一个house,从那个house再到其它的house,直到到达终点。
我们要对题中输入的每一条边,分别找到离最近的house(这可以使用Dijkstra解决),设为,这样从到,可以经过边,且代价为。这样我们就组成了一个新的图。
举个例子,样例中建出的新图,有三个点,有两条边。
如果我们定义新图中一条路径的价值为经过边权的最大值(即Takahashi至少要保存清醒的时间)。那么对于询问,我们就是查询新图中连接它们所有路径中价值最小的那个。
法1:
我们将询问离线。从小到大加入新图中的边,使用并查集查询在时刻,是否在同一个联通块中。
法2:
在线解决。不难发现价值最小的那个路径一定在最小生成树中,因为Kruskal的过程就是从小到大依次加边(用权值最小的边合并两个连通块),遇到环就不加入,故在生成的树中的路径一定是最大值最小的。
所以,对于从到,我们可以放到生成树中,倍增解决,找到所需的最小代价,和比较大小即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话