7月AT杂题

AtCoder Beginner Contest 308

G - Minimum Xor Pair Query

sto GM_Joanna orz

这是一个神奇的 trie 树做法。

首先,没有删除操作的时候用 trie 你是会的,现在我们来想想怎么维护删除操作。记 \(m_u\) 表示在以 \(u\) 为根的子树内,任选两数异或的最小值(若凑不满两个则为无穷大),我们考虑类似线段树一样从下往上依次更新答案。

记左右儿子为 \(ls,rs\)\(c_u\) 表示在以 \(u\) 为根的子树内有多少个数,下面开始大力分讨:

  • 如果 \(c_u<2\),说明凑不满两个数,\(m_u=\infty\)

  • 如果 \(ls\) 不存在,说明我们只能从 \(rs\) 转移,\(m_u=m_{rs}\)\(rs\) 不存在时同理;

  • 如果 \(\max(c_{ls},c_{rs})\ge 2\),说明我们可以选出两个数使得它们异或起来当前位为 0,这一定是最优的,故 \(m_u=\min(m_{ls},m_{rs})\)

  • 如果都不成立,说明一定是左右儿子中各有一个数。那我们直接对于这种子树中只有一个数的节点,记录一下这个数具体是多少,记为 \(p_u\),有 \(m_u=p_{ls}\oplus p_{rs}\)

时间复杂度 \(O(n\log V)\)


这里还有两种做法。

  • 首先是我赛时想出来的做法:容易发现最优的两个数排序后一定相邻,所以拿 set 乱搞即可。但这个性质我不想证也不会证,所以 copy 一下 robinyqc 的证明。

    • \(v_n\) 表示 \(v\) 在二进制表示下从低往高数第 \(n+1\) 位,比如 \(v_0\) 表示最低位(第一位)。设 \(x\)\(z\) 二进制表示下 \(k+1\) 位及以后完全相同。那么第 \(k\) 位,由于 \(x<z\),必定满足 \(x_k=0\)\(z_k=1\)。因此 \((x\oplus z)_k=1\) 并且 \(\forall 0<j<k,(x\oplus z)_j=0\)。因此 \(2^k\leq x\oplus z<2^{k+1}\)

    • \(x\)\(y\)\(i+1\) 位及以后相同,同理 \(2^i\leq x\oplus y<2^{i+1}\);设 \(y\)\(z\)\(l+1\) 位及以后相同,同理 \(2^l\leq y\oplus z<2^{l+1}\)

    • 因为 \(x<y<z\),显然 \(i,l\leq k\)。并且,若 \(y\)\(k\) 位为 \(1\)(即 \(i=k\)),那么 \(l<k\);若 \(y\)\(k\) 位为 \(0\)(即 \(l=k\)),那么 \(i<k\)。也就是,\((i<k)\lor (l<k)\) 恒成立。那么 \((2^{i+1}\leq 2^k)\lor (2^{l+1}\leq2^k)\) 恒成立。因为 \(x\oplus y<2^{i+1}\)\(y\oplus z<2^{l+1}\)\(2^k\leq x\oplus z\)。那么不等式的放缩是可行的,\((x\oplus y<x\oplus z)\lor (y\oplus z<x\oplus z)\) 恒成立。也即 \(x\oplus z>\min(x\oplus y,y\oplus z)\)

    • 这个结论可以继续推广一下,就得到了刚刚我们要证明的东西。

  • 然后是另一种线段树分治的 \(O(n\log n\log V)\) 的做法:每个数会在时间轴上一段区间内存在,你可以把这个区间对应到线段树上 \(\log n\) 个区间,最后在线段树上 dfs 一遍即可知道哪些数会有效,像 CDQ 一样搞搞即可。

AtCoder Regular Contest 163

C - Harmonic Mean

结论:\(\dfrac{1}{a}=\dfrac{1}{a+1}+\dfrac{1}{a(a+1)}\)

\(n\le 2\) 特判掉,然后尝试从 \(n=3\) 开始利用上式拓展即可。

posted @ 2023-07-03 07:51  xx019  阅读(15)  评论(0编辑  收藏  举报