Codeforces 241B: Friends

1.  题目大意

    给出\(n\)个非负整数\(a_i\),两两配成无序对,每对\((a_i, a_j)\)的好看度为\( a_i \oplus a_j \)。请选出\(m\)对使得好看度之和最大。

    其中\(\oplus\)表示异或。

 

2.  数据范围

    \( 1 \le n \le 5 \cdot 10^4 \)

    \( 0 \le m \le \frac { n \cdot (n - 1) } 2 \)

    \( 0 \le a_i \le 10^9 \)

 

3.  题解

    记\( w =max\{ log_2 a_i \} \)。

    将算法分为两部分:

        1. 求出最大的\(l\)使得满足\(a_i \oplus a_j \ge l\)的数对的个数不小于\(m\);

        2. 对这些数对的好看度求和。

    对于第一步,我们可以将所有\(a_i\)插入Trie,在Trie上走一走,每次从高到低贪心考虑每一位,检查一下这一位置为1后满足条件的个数是否超过\(m\)。这样我们就可以在\( O(nw) \)的时间复杂度内求出\(l\)及好看度大于\(l\)的对数\(c\)。

    对于第二步,我们可以把每个\(a_i\)放在Trie上跑,就可以把原问题分解成Trie上若干棵子树中所有数与\(a_i\)异或之和。如果记录子树内每一位为1的个数,那么空间复杂度是\(O(nw^2)\)的。考虑到每棵子树在dfs序中是一个区间,我们就可以做个前缀和,然后用对应区间相减即可。这样我们就得到了好看度大于\(l\)的数对的好看度之和\(s\)。

    最终答案即为\(s + l \cdot (m - c)\)。

 

4.  时间复杂度

    时间复杂度:\( O( nw^2 ) \)

    空间复杂度:\( O( nw ) \)

 

5.  代码

    代码在这里

    我的实现中空间复杂度是\(O(nw^2)\)的。

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com