3.15 CW 模拟赛 T4. 完美的答卷
前言
希望我的方法是一种完美的答卷吧
宁可做错, 也不能什么都不做
-
点对问题
- 点对贡献维护, 类似扫描线的思路, 一维枚举
- 一维数据结构处理
- 往往可以通过之前计算过的 \(l\) 来继承, 类似 \(\rm{dp}\)
- 一般来说, \(L\) 从右往左, \(R\) 从左往右枚举
- 点对贡献维护, 类似扫描线的思路, 一维枚举
-
二进制相关问题
- 往往可以拆成每一位考虑 \((\)贪心\()\)
- 异或
- 注意结合律
- 同值异或可以无视
- 可以前缀和, 拥有逆运算
- 本质上是对位的取反
- 与运算
- 往往用与 \(0\) 来固定值, 用与 \(1\) 来保留值
- 或运算
- 往往用或 \(1\) 来固定值, 用或 \(0\) 来保留值
- \(01 \textrm { trie}\)
- 最值问题
思路
题意其实非常形式化不太需要分析, 因此直接端上来
题意
给定序列
求
直接想似乎没什么思路, 看一下 \(\rm{subtask}\), 发现其中性质 \(\textrm{A: } a_i \leq a_{i + 1}\) 好像比较有用
性质 \(\rm{B}\) 是简单结论, 赛时猜出来自己证伪了, 比较的唐诗, 这个故事告诉我们证伪的时候要严谨, 最好把它记在过程上
考虑性质 \(\textrm{A: } a_i \leq a_{i + 1}\)
不难发现相当于钦定了区间贡献为两端点异或和
于是我的神奇想法就变成了枚举右端点, 左端点维护 \(01 \textrm{ trie}\), 然后以此 \(\mathcal{O} (n \log \mathcal{R})\), 这很对, 但是赛时认为这么复杂的东西只给 \(8 \textrm{ pts}\), 简直不是人所以去想更简单做法了, 殊不知这可以直接通向正解
你发现本题求 \(\max \{f\}\), 想到枚举两个值作为区间 \(\max, \min\), 判断是否存在区间
不难发现一个性质, 倘若设这两个值的位置是 \(i, j\), 那么存在区间当且仅当区间 \(\Big[\min(i, j), \max(i, j)\Big]\) 的最值恰好在两端, 这个很显然吧
显然不可以直接枚举两点, 考虑点对问题的常见做法, 一维枚举维护一维
首先假设当前位置为 \(p\) , 我们钦定当前位置作为最小值, 然后序列翻转再做一遍就好了, 易于处理, 顺天
当前要找的是作为最大值的位置 \(q\), 显然在 \([1, p]\) 组成的单调栈上
还有一个问题是要确保 \(q\) 在第一个比 \(a_p\) 小的位置之后
现在我们知道符合条件的 \(q\) 组成的集合, 如何快速维护其最值?
不难发现可以用 \(01 \textrm{ trie}\), 但是要求动态维护符合要求的 \(q\), 其实并不简单, 但题解一笔带过了, 神秘
初步的想法是对于 \(\rm{trie}\) 上的节点, 我们维护一个值表示其子树中的最大编号, 这样就可以简单的判断 在第一个比 \(a_p\) 小的位置之后, 但是我们还需要维护插入删除应该怎么做
发现插入删除是一个栈的过程, 也就是相当于插入撤销求最值, 显然的, 我们可以用栈维护当前的最大值
然后就做完了
实现
这道题着重考量对字典树的维护
当然也比较考验码力
对于每个节点维护一个栈是可行的吗? 猜测空间复杂度可以卡到 \(\mathcal{O} (n^2\log \mathcal{R})\), 是这样的吗?
发现每个元素的贡献等于其结束点在树上的深度, 也就是 \(\log \mathcal{R}\), 虽然并不是很符合常识, 但是其空间复杂度貌似是 \(\mathcal{O} (n \log \mathcal{R})\)
因此先维护第一个比 \(a_p\) 小的位置, 然后做做做
总结
关键步骤: 证伪/性质/推导 应当记录下来并理清楚
最值类问题也许可以搞成判定类问题处理
分讨注意不重不漏
维护神秘 \(\max, \min\), 往往可以尝试单调栈/单调队列
插撤查问题往往可以使用类似栈的结构维护
树上问题的复杂度往往比较的神奇, 不能靠直觉判定, 应该冷静证明
然后这个也涉及到了
贪心的令不等式的条件最容易成立, 只要有一个成立即可
从而转化成了维护最值的问题