P7838 解题报告
题解
method 1 暴力
信仰 ,谁试谁爽。
method 2 观察性质
首先取掉 ,然后就不管它了,现在还剩下 个数。
在不取数的情况下,数列中点在第 个数和第 个数之间。每次在删除一个数后,中点会移动到第 个数或者第 个数。并且容易发现如果删除的数在左边的一段,中间的数会往第 个数移;如果删除的数在右边的一段,中间的数会往第 个数移。并且取掉这个数以后,原来被中点分成的两端现在仍然被中点隔开,也就是说,我们始终是在前一半取一个数,后一半取一个数,并且这两个数中至少有一个与中点相邻,所以我们把整个数列看成两个子数列 和 ,其中 为 ~, 为 ~。我们每次进行的操作就是从一个数列中取出最后一个数,再从另外一个数列中删掉任意的一个数,询问最多取出多长的连续数字。
我们在完成一个取数然后抵消的事情,如果某个数列(假设是数列 )底部的某个数在所枚举区间内,我们肯定要想办法把它拿出来,并且 中和这个要选的数抵消的数一定不能在区间内,那我们取哪个数比较好呢?显然,如果选较前的数,较后的数就容易跑到数列的末端,如果两个不在区间内的数都到了序列末端,那就必须取掉至少一个,就相当于浪费了这个原本可以抵消掉的数。所以我们应该每次尽量选靠后的数来抵消,所以每次取 最后一个不在区间内的数和 的最后一个抵消就好了。当然,如果 和 尾端的两个数都不是区间内的数,那就只能被迫让它们互相抵消。所以如果枚举到某个在区间内的数,另一个数列中没有能与它抵消的了,这个区间就不满足答案应该有的性质;如果成功抵消完了,这个区间就是满足的。
然后似乎就不能在区间这个条件上动手脚,就只能枚举这段连续数字了,然后模拟上述操作,依次判断,时间复杂度 。
method 3 双指针
显然如果区间 是满足的,那么区间 和 就都是满足的。对于这种性质,我们可以双指针维护,就可以不用分别枚举 和 了,可以做到 。
method 4 线段树
发现双指针每次只修改一个数,如果每次都重新模拟一遍很亏,所以考虑能不能数据结构维护。
因为我们每次都是取最靠近 尾端的一个非区间内的数来抵消掉 的最后一个数,只考虑 在区间内数的抵消情况时,如果 数列中靠前的数都能有 数列中的数与其抵消,并且 数列中截至这一位不在区间内的数的数量大于等于 数列截至这一位在区间内的数的数量时, 数列截至这一位都是能被抵消的,所以我们可以记录 数列在区间内的数的数量的前缀数组和 数列不在区间内的数的数量的前缀数组,保证 的前缀数组每一位都大于 的前缀数组。考虑 在区间内的数抵消情况同理,但是因为 和 中的数的数量是相等的,所以如果 中在区间内的数的数量大于 中在不区间内的数的数量,那么 中在区间内的数的数量一定大于 中在不区间内的数的数量,所以考虑其中一个就可以了。
那么用线段树维护 的前缀数组与 的前缀数组的差,使其最小值保持在 以上即可,复杂度 。
代码
__EOF__

本文链接:https://www.cnblogs.com/vegtable-foraino/p/16250074.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!