问题描述
对于长度为 $n$ 的数组 $a$,如何计算所有数对的或运算结果之和,即
如对于数组 [1,2,3],结果为 (1|2)+(1|3)+(2|3)=3+3+3=9。
问题分析
最直接的方法就是遍历所有结果:
|
|
但是这样做的时间复杂度为 $\mathcal{O}(n^2)$,事实上存在 $\mathcal{O}(n)$ 的方法。
注意到 $a|b$ 的结果不会减少 $b$,而是在 $b$ 的基础上,加上二进制表示中所有 $a$ 为 1 而 $b$ 为 0 的位的位权。
如 $a|b=1|2=(01)_2|(10)_2=b+(1)\times(1\ll0)=3$。
所以对于第 $i$ 位,假设该位为 0 和为 1 的数量分别为 $b_0,b_1$,那么该位对结果的贡献为:
$1\ll i$ 表示左移 $i$ 位,即第 $i$ 位的权重。
|
|