Hard
You are given an integer array nums.
Partition the array into three (possibly empty) subsequences A, B, and C such that every element of nums belongs to exactly one subsequence.
Your goal is to maximize the value of: XOR(A) + AND(B) + XOR(C)
where:
XOR(arr) denotes the bitwise XOR of all elements in arr. If arr is empty, its value is defined as 0.AND(arr) denotes the bitwise AND of all elements in arr. If arr is empty, its value is defined as 0.Return the maximum value achievable.
Note: If multiple partitions result in the same maximum sum, you can consider any one of them.
Example 1:
Input: nums = [2,3]
Output: 5
Explanation:
One optimal partition is:
A = [3], XOR(A) = 3B = [2], AND(B) = 2C = [], XOR(C) = 0The maximum value of: XOR(A) + AND(B) + XOR(C) = 3 + 2 + 0 = 5. Thus, the answer is 5.
Example 2:
Input: nums = [1,3,2]
Output: 6
Explanation:
One optimal partition is:
A = [1], XOR(A) = 1B = [2], AND(B) = 2C = [3], XOR(C) = 3The maximum value of: XOR(A) + AND(B) + XOR(C) = 1 + 2 + 3 = 6. Thus, the answer is 6.
Example 3:
Input: nums = [2,3,6,7]
Output: 15
Explanation:
One optimal partition is:
A = [7], XOR(A) = 7B = [2,3], AND(B) = 2C = [6], XOR(C) = 6The maximum value of: XOR(A) + AND(B) + XOR(C) = 7 + 2 + 6 = 15. Thus, the answer is 15.
Constraints:
1 <= nums.length <= 191 <= nums[i] <= 109class Solution {
fun maximizeXorAndXor(nums: IntArray): Long {
val n = nums.size
val full = 1 shl n
val xorMask = IntArray(full)
val andMask = IntArray(full)
val orMask = IntArray(full)
for (mask in 1..<full) {
val lb = mask and -mask
val i = Integer.numberOfTrailingZeros(lb)
val prev = mask xor lb
xorMask[mask] = xorMask[prev] xor nums[i]
andMask[mask] = if (prev == 0) nums[i] else andMask[prev] and nums[i]
orMask[mask] = orMask[prev] or nums[i]
}
var best: Long = 0
val all = full - 1
for (b in 0..<full) {
val andB = andMask[b].toLong()
val rest = all xor b
if (andB + 2L * orMask[rest] <= best) {
continue
}
var a = rest
while (true) {
val c = rest xor a
val sum = xorMask[a] + andB + xorMask[c]
if (sum > best) {
best = sum
}
if (a == 0) {
break
}
a = (a - 1) and rest
}
}
return best
}
}