ARC127D

题面

link

​ 给定序列\(A\)和序列\(B\),求\(\sum_{1\le i<j\le N}\min(A_i\oplus A_j,B_i \oplus B_j)\)\(\oplus\)为异或。

题解

​ 先考虑怎么求\(\sum_{1\le i<j\le N}A_i\oplus A_j\)

​ 拆位,然后对每一位求这一位是\(0,1\)的数有多少,对答案的贡献就是\(cnt[0]\times cnt[1]\)

​ 加上了min之后,肯定是要去除掉min带来的影响。

​ 一个超级厉害的东西:考虑比较两个二进制数,肯定是前面几位相等,之后有一位不相等,那我们判断大小的关键就是那一位。

​ 那怎么求出这一位呢——异或!看\(A_i\oplus A_j\oplus B_i \oplus B_j\)哪一位为1,那么这一位就是判断大小的一位。

​ 然后发现这可以换一下位置:即\((A_i\oplus B_i)\oplus(A_j \oplus B_j)\)。那么就可以设\(C_i=A_i\oplus B_i\),根据\(C_i\)在这一位的不同将序列分治,处理已经分出大小的序列,然后不断向下递归。

​ 具体来说,可以将序列按\(C_i\)排序,然后对于位数,求出该位0和1的分界\(mid\),即\([l,mid-1]\)是0,\([mid,r]\)是1。然后对于每个i你都是知道其\(A_i\)\(B_i\)的。那么你就可以将其分为四组,按上面的计算方法计算贡献:

  • \(A_i\)这一位是\(0\)\(B_i\)这一位是\(0\)\(A_j\)这一位是\(0\)\(B_j\)这一位是\(1\),此时产生贡献的是\(A_i \oplus A_j\)
  • \(A_i\)这一位是\(0\)\(B_i\)这一位是\(0\)\(A_j\)这一位是\(1\)\(B_j\)这一位是\(0\),此时产生贡献的是\(B_i \oplus B_j\)
  • \(A_i\)这一位是\(1\)\(B_i\)这一位是\(1\)\(A_j\)这一位是\(1\)\(B_j\)这一位是\(0\),此时产生贡献的是\(A_i \oplus A_j\)
  • \(A_i\)这一位是\(1\)\(B_i\)这一位是\(1\)\(A_j\)这一位是\(0\)\(B_j\)这一位是\(1\),此时产生贡献的是\(B_i \oplus B_j\)

启发

  • 对大小关系的判断可以考虑异或!
  • 可以分治计算这种需要对于每对\((i,j)\)计算其贡献的题。
posted @ 2022-02-17 17:13  qwq_123  阅读(52)  评论(0编辑  收藏  举报