专栏文章

题解:P7115 [NOIP2020] 移球游戏

P7115题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@miqnszst
此快照首次捕获于
2025/12/04 07:49
3 个月前
此快照最后确认于
2025/12/04 07:49
3 个月前
查看原文
暑假 vp 的时候连 n=2n=2 的常规解法都没想到,于是一波爆搜强行构造 n=2n=2 方案喜提 1010 分。
当时还不会按照值域 0/10/1 分治的 trick,不过后来见到了无数次这种 trick。
我印象中这个题也是分治构造的。 P9731 [CEOI2023] Balance
下文中将柱子称为栈 ss,毕竟两者的用法是一样的。
先思考 n=2n=2 时候的解法,记录两个栈为 s1s_1s2s_2,分别目标为 11 球和 22 球。我们现在想要其中一个栈变成全 11。我们发现 s1s_1s2s_2 都往空栈里面放一点东西进去似乎只有暴搜放进去的顺序然后 2233 栈互相搞一下的很暴力的做法,没有可扩展性。
有没有什么好办法去分离 1122 两种小球呢,只有两个空栈能办到。我们现在只有一个空栈,转念一想,其实我们可以再创造两个半空栈,设 s1s_1 中有 aa11,那么我们只需要从 s1s_1 中挪 min(a,ma)\min(a,m-a) 个球给 s3s_3。不妨设 a<maa<m-a,然后将 s1s_1 中球依次弹出,如果是 11 则放入 s2s_2 中,如果是 00 则放入 s3s_3 中,这次操作把部分 0011 聚集在了一起。
接着,把 s2s_2s3s_3 栈顶的 0/10/1 段全部再放回 s1s_1 中,这一步我们实现了对于 s1s_1 的排序。
s2s_2 中的所有数移动到 s3s_3 中,再把 s1s_1 中顶端的 11 段放入 s2s_2 中。这一步我们实现了将 0011 段分别独立地放在 s1s_1s2s_2 中。
然后就是处理 s3s_3 了,我们只需要根据是 00 还是 11 分别放入 s1s_1 或者 s2s_2 即可。
这样子我们就完美解决了 n=2n=2 的情况。
那么对于 n>2n>2 的时候呢?把问题转化到 n=2n=2
我们设 solve(l,r)\operatorname{solve}(l,r) 表示正在处理颜色为 [l,r][l,r] 范围内的球。我们将 xmidx\le mid 的球全部看成一种颜色,将 x>midx>mid 的球看成另一种颜色,然后执行 n=2n=2 的算法就可以将 xmidx\le mid 的球放在一起,x>midx>mid 的球放在一起,然后再分别进行操作 solve(l,mid)\operatorname{solve}(l,mid)solve(mid+1,r)\operatorname{solve}(mid+1,r) 就可以继续分治下去解决问题了。

评论

1 条评论,欢迎与作者交流。

正在加载评论...