牛客寒假训练赛第二场
1|0基本情况
前面过的很顺,F吃满罚时,T4次WA4次最后乱搞过的,K有一点思路,但是码力跟不上,其他没做的题题目基本没思路。
2|0EF
https://ac.nowcoder.com/acm/contest/67742/E
https://ac.nowcoder.com/acm/contest/67742/F
两题虽然都是过了,但一个是提交前改了很久,一个是提交改了很久。
2|1E
思路肯定没别的了,就是我的实现太容易出锅
-
虽然最后过了,两个死亡
while
而且这个pos -= 2
看起来很不舒服,样例也是调了很久才过。 -
2|2F
想了三个解法,前两个超时但是正确性保证,第三个不超时但是部分错误。
最后用第三个解法加上分讨错误部分用第一个解法过了。
总结起来学到几个问题:
- 超时不要慌,先认真分析时间复杂度,看看为什么和预期结果有出入,往往是哪个大的循环不合理,不要一开始就想着优化小细节或者卡常。
一定要记得有 操作- 不要在用迭代器遍历这些容器的循环中进行
-
-
其实就类似于一开始比较暴力的方法,然后再用最后那个部分正确方法的思路优化,先把我一开始的方法贴上来吧
就是把每个颜色对应的每个位置入栈,然后每次出栈最栈顶靠前的颜色。
但是这里我每轮都进行了把位置在当前位置之后的元素都出栈的操作,会超时。
实际上可以通过类似我最后的方法,针对区间处理,每次删完元素就把处理区间转移到
-
下午分析了一下我第一个做法,理论上,时间复杂度明明是对的?
仔细看了一下,发现一个重要问题,我每次跑 while
都要无端遍历一下 color
,但实际上很多颜色已经全部删掉了,注意这里的颜色数是可以到达
这里我的理想状态下,这些不用的颜色自然就 continue
遍历是不耗时的,然而这就是导致我超时的关键原因!事实上光跑一个
set
开来做什么用的?可以直接删除没用的颜色啊!
然而直接这样搞运行时错误
调了二十分钟,突然想到如果我把这个元素删了,set
循环遍历下一个元素毕竟是指针操作,可能指向下一个元素的指针也乱了之类,所以似乎根本没法在循环里面实现边循环边删除,于是我就嗯造了一个数组存要删除的元素(常数接着炸)
令人忍俊不禁的是,这居然就过了。
最后想想也确实,每次把没有的颜色删掉,而颜色的数量很大,本身就是影响时间复杂度的最大因素。
3|0K
https://ac.nowcoder.com/acm/contest/67742/K
想的是爆搜,我码力不够。
-
先贴上
的爆搜
但实际上,仅针对这个
先分析题目条件来想怎么枚举:
-
同字母对应的数码一定相同,不同字母对应的数码一定不同
- 这里我想的是搞暴力枚举然后检查是不是相同,并不直接
- 可以直接从这个性质下手枚举,对
应该赋的值进行枚举,然后通过这个构造数字,就必然符合要求条件。
-
不同字母对应的数码一定不相同
- 接上文,通过 set 来对枚举出来的
去重即可。
- 接上文,通过 set 来对枚举出来的
-
超时?
- 枚举五个数码加上对原数组逐位带入。
4|0C
https://ac.nowcoder.com/acm/contest/67742/C
01字典树,逆元
- 依题意,只有子序列的最大值和最小值对答案产生贡献。
- 对
数组排序,先选定最大值和最小值。 - 满足题意得最大值和最小值之间一共有
个数的话(不包括这两个数),方案数就是
- 对
但是暴力枚举会超时。
-
位运算的特殊性
- 按位运算,互相之间不影响。
- 枚举最大值,看有哪些最小值符合小于等于
-
通过01字典树枚举
-
01字典树从左到右肯定是递增的
- 选好最大值,统计最大值左边的枝干
-
字典树同一个枝干的两个数在枝干上的位异或和肯定是
。 -
按小到大对数编号,因为方案数是
, 而 其中 为最大值, 为要找的符合条件的最小值, 为除去它两之外的区间元素数目。
-
-
对于一个
,它贡献的答案为 。我们可以将这个式子拆掉: ,于是 与 就分离了。所以我们可以把 插入 。当 时,在 Trie 中查询 ,此时贡献为 。 与 都可以预处理求出 ( 要用到逆元)。然后枚举 ,每次在 Trie 中查询,总时间复杂度为 。 -
因为该题模数是质数,可以直接用费马小定理推得逆元为
- 快速幂边算边取模即可。
5|0GH
https://ac.nowcoder.com/acm/contest/67742/G
https://ac.nowcoder.com/acm/contest/67742/H
线段树及其进阶应用
5|1G
显然是一个数据结构题,需要支持两种操作:
-
单点修改
-
区间查询,在查询的区间中选出一个子段,再把子段切成两部分,求前一个部分的和减去后一个部分的和的最大值。
对于查询操作,有两个问题:
- 怎么选子段?
- 把子段切成两部分,在哪切?
可以看到 easy 版本中数字都是非负数,稍加思考可以得到两个显然的贪心结论:
- 假设我们已经选出了一个子段
,那答案必定为 ,也就是说 easy 版本省去了问题2 "在哪切"。 - 再多思考一下会发现,问题1 "怎么选" 也得到了简化。因为数字都是非负数,查询求的是前一段和-后一段和最大,所以前一段肯定尽可能长。那么对于查询的区间
来说,肯定选 这个子段,那答案就变成了 。也就是说只要确定了 ,就能得出答案。
根据上述两个结论,现在考虑如何求答案。
考虑维护区间中每个
令
但这个式子还与
- 维护
: - 维护
于是
注意此时单点修改
我们可以使用线段树维护,支持 "区间加","区间求
时间复杂度
__EOF__

本文链接:https://www.cnblogs.com/kdlyh/p/18009528.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下