位操作:更难翻转硬币

Posted

技术标签:

【中文标题】位操作:更难翻转硬币【英文标题】:Bit Manipulation: Harder Flipping Coins 【发布时间】:2018-04-15 07:00:44 【问题描述】:

最近,我从 CodeChef 看到了这个题为“Flipping Coins”的问题(链接:FLIPCOINS)。

总而言之,有 N 个硬币,我们必须编写一个支持两种操作的程序。

    在 [A,B] 范围内抛硬币 分别查找范围 [A,B] 内的正面数。

当然,我们可以快速使用分段树(范围查询,使用惰性传播的范围更新)来解决这个问题。

但是,我遇到了另一个类似的问题,在一系列翻转后(操作 1),我们需要输出翻转后的硬币排列结果(例如 100101,其中 0 代表头部,1 代表尾部)。

更具体地说,操作 2 从计算正面数量变为产生所有 N 个硬币的结果排列。此外,新的操作 2 所有翻转完成后调用(即操作 2 是最后一个被调用的,并且只被调用一次)。 p>

我可以知道如何解决这个问题吗?根据问题标签,它需要某种形式的位操作。

编辑

我尝试对所有查询进行暴力破解,可惜,它产生了 Time Limit Exceeded。

【问题讨论】:

你好,你能告诉我们你自己的想法吗? 【参考方案1】:

可以使用二进制索引树来打印硬币的状态:

最初所有值都是0。 当我们需要抛硬币[A, B]时,我们将A增加1和 将B + 1 递减1。 硬币i 的状态是i 处的前缀和模2

之所以有效,是因为i 处的前缀总和始终是i 处完成的翻转操作数。

【讨论】:

如果只做增量和减量而没有范围求和,为什么还需要 BIT? 我们需要前缀和来确定每个硬币的状态。 x 的前缀总和是直到 x 的所有元素的总和。 但是你只需要在最后执行一次(OP 说“即操作 2 是最后一个被调用的,并且只被调用一次”)。

以上是关于位操作:更难翻转硬币的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯 [翻硬币] 贪心

P1146 硬币翻转

luogu P1146 硬币翻转

按位运算符简单地翻转整数中的所有位?

洛谷——P2708 硬币翻转

洛谷——P2708 硬币翻转