-
假设当前每一列的数字都属于 \([l,r]\),把属于 \([l,mid]\) 的数字视为 \(0\), \([mid + 1,r]\) 视为 \(1\)。
那么把属于 \(0\) 和 \(1\) 的数字分开,保证每一列全为 \(0\) 或 \(1\),然后递归求解子问题。
-
任意两列 \(u,v\) 至少有一种数字次数不少于 \(m\),不妨设为 \(0\)。
可以把 \(0\) 填满 \(u\),剩下的放到 \(v\),然后就不考虑 \(u\),从前往后扫一遍。
-
具体的设 \(u,v\) 分别有 \(cu, cv\) 个 \(0\)。
将把 \(x\) 的顶部移到 \(y\) 的顶部,移到 \(k\) 次记为 \(move(x,y,k)\)。
\(move(v,n+1,cu)\)
然后依次把 \(u\) 中数字为 \(0\) 的放入 \(v\),否则放入 \(n + 1\)。
\(move(v,u,cu)\),\(move(n + 1,u,m - cu)\),\(move(v,n+1,m-cu)\),\(move(u,v,m-cu)\)。
现在 \(u\) 只有 \(0\),\(v\) 只有 \(1\),只需要把 \(n + 1\) 的数字依次放入 \(u,v\) 即可。
-
一共递归 \(\log n\) 次,每一层至多操作 \(n\) 次,每次需要 \(O(m)\) 的次数。
所以需要 \(O(nm\log n)\) 次操作。