8.23
护照
在第 个点买一张票,就能在 中任意行走,求从每个点出发,最少买几张票能走遍 ?
tag:最短路,线段树优化建图。
题目的问题是求最少代价,于是我们发现题目很像一个最短路模型: 向一个虚点 连边权为 的边, 向 连代价为 的边。连边看起来很多,但是由于连边连向的是一个区间,我们只需要线段树优化建图即可。
考虑最终的答案是什么:由于连边是连向一个区间,所以对于点 ,所有买的票的并,也就是我们能走到的点,构成了一个大区间。所以走遍 的充要条件是走到 。因为 为该区间左端点。同理走遍 的充要条件是走到 ,因为 为该区间右端点。所以我们建反图并从 与 分别跑最短路,每一个点的答案应该是到 的最短路加上到 的最短路。
然后我们发现这个不对,因为到 的最短路和到 的最短路会有重复的路径,这一段路径只会被计算一次。例如,从点 出发只需要买一张 的票就可以了。
我们如果设初始 为初始答案 ,那么我们发现对于任意的 ,。于是我们考虑再次使用最短路,只不过这一次往优先队列中加入所有点作为源点进行松弛。
如果对算法进行思考,我们会发现只需要将所有票的虚点作为源点即可。原因如下:
- 对于线段树上的点,它们只负责联通原始图中有边的点,从其出发的边权值都为 ,因此不用松弛。
- 对于原有点,我们建的反图中必定有票的虚点连向原有点的边,因此只要不是无解情况,原有点必定会被松弛到。
Election
由
c,t
组成的字符串,每次询问一个区间,问至少需要删掉多少个t
,才能使在子区间任意一段前后缀里,c
的个数都不小于t
的个数。
tag:线段树
两类字符比大小,很经典的操作就是把一个视为 ,另一个视为 。这里我们把 c
视为 ,把 t
视为 ,那么原问题转化为:需要删掉多少个 ,才能使子区间任意一段前后缀和都不大于 。
考虑先满足前缀,再满足后缀。我们贪心地删除:如果这一个 会使前缀大于 ,我们才将它删除。这不仅用最少的次数满足了前缀都不大于 的限制,还将删除的点尽量右移。这会使后缀的修改更优。
考虑用变量描述前缀需要的最大删除数。我们设变量 表示 到 的前缀和,可以发现当我们修改了 变为 时,之后我们第一个修改的 必定大于 ,且修改的次数变为 。那么只满足前缀的答案是 。
现在考虑后缀。后缀的难点在于我们已经提前删除了一部分 了。于是我们考虑删除了多少。对于点 ,之前在满足前缀过程中删除的点为 ,那么之后删除的点为 。所以若设原序列 到 后缀和为 ,新序列后缀和为 ,那么 。
考虑最终答案 ,把脑子放进垃圾桶,我们来推式子:
发现这实际上就是前缀的最大值加上在它右边的后缀的最大值。用线段树维护即可。
y-fast trie
给出常数 和一个初始为空的集合 ,你需要支持以下操作:
- 增加一个数 ,保证 在 中没有出现过。
- 删除一个数 ,保证 。
在每次操作后,你需要输出 。强制在线。
tag:模型刻画。
首先不难发现取模实际上把答案分成了两种, 和 。
于是把 分类。分成 和 。对于前者,我们找出 内的最大的两个数匹配即可。下文着重考虑 的情况。
对于 ,发现 随着 的增加而增加,直到 为止。所以 会选择其中最大的 。一种暴力的想法是,我们对于每个 ,找出使 的 的最大值。时间复杂度 ,具体取决于集合内数的个数。
考虑优化这个暴力。对于每个 ,发现 随着 的增加而增加,直到 为止。所以 会选择其中最大的 。于是 和 就从单项选择变为了双向选择。这是很好的,因为这就意味着所有 和 两两匹配。
考虑维护匹配。对于增加操作,我们找到其作为 能匹配到的最大的 ,如果 没有匹配则可以直接匹配。否则若 比与 匹配的点更优,我们就扔掉 匹配的点,并将其与 匹配。如果匹配更新,则也要与当前答案比较。
对于删除操作,若没有匹配,可以直接删除。若有匹配,我们需要在删除 后另外为 寻找匹配。这是增加操作做的事情。因此我们删去两个数,并再次增加 即可。这些操作都可以使用 set
完成,时间复杂度 。
意外地难写。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异