ABC475
依旧 ABCDE,然后 E 是第 99min 极限过的!
感觉本场 D 和 E 的 gap 挺大的,ABCD 都是一眼题,E 想了半天,还有一些细节。
E

你怎么知道我 99min 过了 E(
首先把每个人的答案和正确答案逐位比较,相同就是 1,不同就是 0。于是每个人变成一个长度为 \(k\) 的 0/1 串。
观察判定过程:如果满足条件,可以晋级,就直接把这些扔掉就可以了;如果没有满足条件就淘汰,然后淘汰的也可以扔掉了。可以发现,这就是在一棵二叉树上进行的操作,更准确地,这是是在一棵 0/1 Trie 上走:
- 当前所有还没被确定的人,一定共享某个前缀。
- 对于第 \(j\) 题,看这个未确定集合里答对的人数。
- 如果晋级后满足阈值 \(m\),那么这些答对的人全部晋级,未确定集合变成答错分支。
- 否则,答错的人全部淘汰,未确定集合变成答对分支。
于是我们只需要维护所有 0/1 串的 Trie,以及每个 Trie 节点上有多少个串经过。
修改怎么办?因为 \(q\) 只有 \(5\times 10^4\),\(k\) 只有 \(200\),每次暴力把这个人旧的串从 Trie 里删掉,翻转一位,再把新串插回去,然后从根开始模拟判定过程即可。每次 \(O(k)\),总复杂度 \(O((n+q)k)\)。
判断这个人是否晋级:如果当前题选择的分支和他这一位不同(当前往晋级的方向走,他却被淘汰了;或者当前往本题答错的方向走,他却答对了),那么他就在这一步被确定。如果一直走到最后还没被确定,根据题意,他应该被淘汰。
代码里用 bitset<K> 存每个人的 0/1 串,Trie 节点 cnt 维护经过数量。注意删除旧串时 cnt 减一,插入新串时 cnt 加一。NODE 开 \(2\times 10^7\) 够用。

浙公网安备 33010602011771号