【NOIP2020】移球游戏

  • 假设当前每一列的数字都属于 \([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)\) 次操作。

上一篇:HEVC编码结构简要总结


下一篇:python学习4--python3连mysql增删改查