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)\)计算其贡献的题。