Official

C - Combine to Make Non-decreasing Editorial by evima


We want to maximize the number of intervals when dividing into several intervals such that the bitwise OR of each interval is non-decreasing.

Let \(\mathrm{dp}_{i,x}\) be the maximum number of intervals when the \(i\)-th element from the beginning of \(a\) is the left end of the currently focused interval and the bitwise OR of the previous interval is \(x\).
Naively performing this DP takes about \(O(N^2)\), so improvement is needed.

Let \(f(l,r) = a_l \ \mathrm{OR} \cdots \ \mathrm{OR} \ a_r\).
When \(r\) is fixed, we obtain about \(\log( \max(a_i))\) intervals \([l_1, l_2)\) where the value of \(f(l,r)\) equals \(x\) if and only if \(l_1 \le l < l_2\).

We sort these \(N \log( \max(a_i))\) intervals in ascending order of the value of \(f(l,r)\), and break ties so that smaller \(r\) comes first when \(f(l,r)\) values are the same.
Since we sorted in ascending order of \(f(l,r)\) values, we can drop the \(x\) part of \(\mathrm{dp}_{i,x}\).

We perform the transition of replacing \(\mathrm{dp}_{r+1}\) with \(\max(\mathrm{dp}_{r+1}, \mathrm{dp}_{l}+1)\) for \(l\) satisfying \(l_1 \leq l < l_2\).
This is RMQ, so it can be computed in \(O(\log N)\) using a segment tree.

We can find the answer in about \(N \log( \max(a_i)) \log (N)\) time, which is sufficiently fast.

posted:
last update: