题目大意
定义f(x,y)=(x|y)−y,有一个数组A可以为[a1,a2,…,an],重排A中的元素使得f(f(…f(f(a1,a2),a3),…an−1),an)的值最大,输出重排后的A
题解
思路1:
对于式子f(x,y)=(x|y)−y,考虑x和y的二进制位
当y的第i位是1的时候,x的i位是0还是1对结果的第i位都没有影响,结果的第i位都是0
当y的第i位是0的时候,结果的第i位等于x的第i位
最终的结果只和把谁放在A中第一的位置有关,也就是说对于a1,a2,a3,…,an如果想把其中的一个数字x放在第一个,那么当x的第i位是1的时候,数组中的其他数字的第i位必须全部是0函数的结果的第i位置才能取得1,如果x的第i位是0的话,那么函数的结果的第i位一定是0,所以对与每一个ai我们都算一下函数的最终结果,然后把最大的位置的那个放在第一个即可。
以上思路来自Akura_Mea
1 |
|
思路2:
官方题解的做法是f(x,y)=(x|y)−y=x&(∼y),
要求f(f(…f(f(a1,a2),a3),…an−1),an),
等价于求a1&(∼a2)&(∼a3)&…&(∼an−1)&(∼an),
从式子可以看出最终的结果只和哪一个放在第一的位置有关,所以维护一个取反的前缀和还有一个取反的后缀和,就能算出哪一个放在a1的位置得到的最终结果最大
1 | def wrapper(func): |
总结
可以看出上面两种思路实现方法不一样,但是原理都一样
v1.5.2