跟着学长做。可能不是很详细。
qoj1875 Nein
link
qoj970 Best Subsequence
考虑单次询问怎么做。二分,设 \(\le W\) 的为一类数,其余为二类数,显然二类数不能相邻,则肯定有一种最优解满足一类数全选了(考虑贪心调整,不证)。复杂度 \(\mathcal{O}(n \log n)\)。
定义答案相邻的一类数,二类数,一类数为一个三元组 \((a, b, c)\),则对于所有 \(i = c\),\(b\) 一定是弹出去的单调栈上的元素之一且 \(a\) 一定是在单调栈上在 \(b\) 前面一个的元素。自证不难。则总的三元组个数是 \(\mathcal{O}(n)\) 的。
又,对于每一个可能的一类数和三元组,他们都对应答案中的一个 \(1\),且都有一个使它存在的 \(W\) 的区间下界 \(W'\),则我们可以考虑把它放到主席树上维护,二分时求一下区间 \(\le W\) 的数的个数即可(注意它是一个环,所以还要考虑两边的情况)。
代码。
qoj1884 Mission Impossible: Grand Theft Auto
先把二度点缩掉。考虑随便定一个非叶子节点为根,将叶子按 dfn 序排序,则有一种覆盖方式就是以某个叶子 \(x\) 为起点,依次覆盖 \((x, x + 1), (x - 1, x + 2), \dots\)
但是,我们发现这样做会有一个问题,就是可能在覆盖的中途漏掉一些边。我们称漏掉的边为 bad 边:

(偷个图,来源)
那你可能会说,直接在覆盖完 bad 边的子树后覆盖一下 bad 边不就行了。但是,需要注意的是 \(x\) 的 bad 边可能有多个,你直接这么搞可能次数就超了。
定义一条边对一个点贡献一次,当且仅当以那个点为起点时,这条边是 bad 边。显然,一条边贡献到的点一定为子树内的中间叶子和子树外的中间叶子(能贡献到当且仅当子树内/外的叶子个数是偶数),且贡献数不超过 \(2\)(可以看图揣摩一下)。
我们发现由于二度点都被缩掉了,则这颗树的总边数不会超过 \(2m - 2\)。分两种情况讨论。
- \(m\) 是偶数:
显然,每个叶子向上连的边一定不会贡献到任何一个节点,剩下的 \(m - 2\) 条边每条边最多贡献 \(2\) 次,总贡献数不超过 \(2x - 4\),则必有一个节点被贡献到的次数 \(\le 1\),取这个点为起点即可。
- \(m\) 是奇数:
此时由于 \(m\) 是奇数,每条边必定会贡献恰好 \(1\) 次。同上文的分析,取被贡献次数 \(1\) 的点为起点即可。
此时,由于所有叶子向上连的边贡献到的点恰好是所有叶子,则此时的 bad 边一定是最后剩下的叶子向上连的边。直接在构造的最后把那个叶子和根覆盖即可。
直接按上面的方法构造即可,复杂度 \(\mathcal{O}(n)\)。
代码(tip:写代码时甚至不需要刻意把二度点缩掉)
IOI 2026 中国国家集训队作业(试题泛做)