|
| 1 | +# Funny Fluffy Tuzi |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +Fluffy Funny Tuzi (FFT) has $N$ piles of carrot lining up in a line, the $i^{th}$ of which has $a_i$ carrots. |
| 6 | + |
| 7 | +Tuzi wants as many carrots as possible. |
| 8 | + |
| 9 | +It can magically merge two adjacent piles $a_{i}, a_{i+1}$ to produce a new pile with $(a_{i} \oplus a_{i+1}) + 1$ carrots. |
| 10 | + |
| 11 | +Here $\oplus$ means binary xor. |
| 12 | + |
| 13 | +Nevertheless, Tuzi does not want to think optimally. |
| 14 | + |
| 15 | +Everytime it will pick the pile with the least carrots, and merge it with one of its adjacent pile(s) so that the new pile has the maximum possible number of carrots. |
| 16 | + |
| 17 | +If multiple piles contain the least number of carrots, then the left-most such pile is chosen. |
| 18 | + |
| 19 | +If for the chosen pile there are two merge choices and both choices yield a pile with the same number of carrots, the the left adjacent pile is merged. |
| 20 | + |
| 21 | +Tuzi will keep merging until there is only one pile of carrots. |
| 22 | + |
| 23 | +It wonders how many carrots it can eventually obtain. |
| 24 | + |
| 25 | +### Input |
| 26 | + |
| 27 | +The first line contains an integer $N$. |
| 28 | + |
| 29 | +The second line contains $N$ integers $a_1, a_2, \dots, a_N$. |
| 30 | + |
| 31 | +输入限制: |
| 32 | + |
| 33 | +$1 \le N \le 500000$ |
| 34 | + |
| 35 | +$0 \le a_i < 2^{30}$ |
| 36 | + |
| 37 | +It is guaranteed that anytime any pile contains less than $2^{31}$ carrots. |
| 38 | + |
| 39 | +### Output |
| 40 | + |
| 41 | +Output a single number: the number of carrots in the final pile. |
| 42 | + |
| 43 | +### Sample Input |
| 44 | + |
| 45 | +``` log |
| 46 | +5 |
| 47 | +3 6 6 7 1 |
| 48 | +``` |
| 49 | + |
| 50 | +### Sample Output |
| 51 | + |
| 52 | +``` log |
| 53 | +7 |
| 54 | +``` |
| 55 | + |
| 56 | +### HINT |
| 57 | + |
| 58 | +不要使用任何与堆和BST相关的STL! |
| 59 | + |
| 60 | +> 注意STL是给c++用的, Java的标准库叫`Java Class Library` |
| 61 | +> |
| 62 | +> 只要不用C++就好了(棒读) |
| 63 | +
|
| 64 | +### 思路 |
| 65 | + |
| 66 | +使用 priority queue 存储当前最小堆积, 元素按照胡萝卜数量与当前位置编号排序, 满足全局最小且左向优先的选择顺序. |
| 67 | + |
| 68 | +链表节点维护双向指针与版本号, 每次从 priority queue 取出的节点若已失效则忽略, 否则计算与左右相邻的 `(val xor neighbor) + 1` 并挑选更大值, 相等时按题意选择左侧. |
| 69 | + |
| 70 | +选择左邻时沿用左节点并更新它的数值与版本, 断开当前节点; 选择右邻时保留当前节点并移除右节点, 双向指针保证每个节点代表连续区间且编号即区间最左端, 因而 tie break 始终正确. |
| 71 | + |
| 72 | +总共执行 `N - 1` 次合并, priority queue 中操作为对数复杂度, 因此时间复杂度为 `O(N log N)`, 额外空间为 `O(N)`. |
0 commit comments