[十二省联考 2019] 异或粽子
如果这道题目会可持久化trie的话,是可以用“超级钢琴”这一道题目的思路去做的
如果不行的话,考虑用trie,但是仍然是“超级钢琴”的思路,由于不会可持久化,所以必须使用一个完整的字典树,于是考虑将\(i<j\)这个条件弱化,然后看这篇题解(关于trie的常用trick的综合可以记住)。这篇题解仍然是“超级钢琴”的思路,“超级钢琴”的思路可以记下,如果往“超级钢琴”上面去想,就可以将这道题目变成如何找出第\(k\)大了
讲一下怎么查找第\(k\)大,不要用二分了,直接把\(sum_r\)放在trie树上查找。trie树每个点记录一下这个点的子树有多少个位置(这个维护方法跟Collapsing Strings的维护方法一样)。对于当前位,如果已经得到位置数加上反方向的位置数的和小于\(k\),那么将已经得到位置数加上反方向的位置数,然后向同方向走(因为向反方向走是达不到第\(k\)大的),否则的话将答案的这一位变成\(1\),然后向反方向走
也就是说查询第\(k\)大根本不用二分,其实上一道题目也没用二分查询第\(k\)大(或者说上一道题目的第\(k\)大与这里的第\(k\)大不同)
update 2026.2.20
下面的做法是错误的,因为那个公式不成立,一个加法是整数加法,另一个加法是布尔加法。但是大方向是正确的(见下一道题目)
给出一种新做法
首先仍然是将\(i<j\)这个条件弱化,找出排名为\(2k\)的异或值\(x\),接下来找出所有大于\(x\)的异或值的和,并且统计有多少个,于是就可以得出\(x\)应该有多少个,然后就可以计算最终的总和
所以难点就是找出所有大于\(x\)的异或值的和,并且统计有多少个
假设现在我们在字典树上查找\(a_i\)的异或值,在当前节点有两条路径,往0走或者往1走。往\(a_i\)当前位相反方向走,得到的数更大;反之更小
如果只能往相反方向走(因为往相同方向走得到的数更小,没有大于\(x\)),那么直接往相反方向走一步
否则的话往相同方向走,但是我们需要统计相反方向的和以及个数
个数比较好统计,在字典树上记录一下每个节点的子树的叶子数目即可
和的话要利用公式\(a⨁c+b⨁c=\bar{a}c+a\bar{c}+\bar{b}c+b\bar{c}=(\bar{a}+\bar{b})c+(a+b)c\)(这里的加法和乘法是与和或)。根据这个公式,我们记录一个节点的子树的所有叶子结点的和以及其取反的和,然后就可以计算和了

浙公网安备 33010602011771号