题意:给两个序列[a, a + n), [b, b + n),求所有数(ai + bj)的异或和,i,j∈[0,n)。
思路:这个题思路比较巧妙,不难但是难想到。BC上的题解讲得非常清楚了,我就直接copy过来了吧
我们考虑两个数A,B。 为了描述方便,我们设[P]的值为:当表达式P的值为真时,[P]=1,否则[P]=0 我们现在考虑计算[(A+B)and(2i)>0] 首先我们将A,B都对2i+1取模,显然这样是不会影响答案的 则有一个十分显然的等式: [(A+B)and(2i)>0]=[(A+B)≥(2i)]−[(A+B)≥(2i+1)]+[(A+B)≥(3∗2i)] 这个式子相当容易理解,这里不多述了 考虑每一位对答案的贡献是独立的,我们每一位分开做 于是现在问题变成了:给定数组A,B,求满足Ai+Bj≥limit的数对个数 我们可以将A,B排序后,直接O(n)计算即可 然而排序是O(nlogn)的,这样总复杂度就是O(nlognlogA)了,无法通过此题 于是这里有个小技巧 我们从高位往低位做,现在我们要实现的是:将A中每个数对P取模后将A排序 我们发现A会被分成两段,一段小于P,一段大于等于P,只有后面一段要取模,我们可以取模后直接将这两段归并,复杂度是O(n)的 时间复杂度:O(nlogA+nlogn)
下面的代码就是根据题解写的,个人感觉也非常清晰了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
|