CF1864E Guess Game

原题

翻译

非常好的一道题,不过前半部分的逻辑推理比较难理解,这很博弈

由于或运算是有1就为1,因此我们对于一对数(a,b),我们不需要看a|b中为0的那些位,因此我们只需要考虑a|b1的情况即可

我们考虑一下如果Alice说"我不知道"说明什么?说明在ab的二进制表示下,a最高位为1。否则如果a最高位为0,则b最高位一定为1,因此Alice一定可以推断出a<b

同理的,在第二轮Bob这里如果b的最高位为0,那他可以直接推断出a>b,因此如果Bob说"我不知道"说明b的最高位也为1。但是我们还要多考虑一点,如果b的最高位为1但次高位为0,那Bob也可以推断出a>b,因为b的次高位为0就说明a的次高位一定为1,也可以推断a>b。因此如果Bob说"我不知道",就把b的最高位和次高位都为1的信息告诉了Alice

第三轮同理,Alice也可以判断a,b的大小关系,或通过说"不知道"来告诉Bob a的次高位和次次高位为1……如此反复,直到一个人找到一位使得a,b中有一个数为0,或判断a=b

在发现这样的逻辑后,我们就可以通过ab对每一位二进制枚举来求出操作轮数。

{a=bpopcnt(a)+1a<bx+[xmod2=0]a>bx+[xmod2=1]

其中x表示a and b在二进制下最高位0的位置(肯定是不算前导0的),popcnt(x)表示x二进制下1的个数

于是我们就可以得到一个O(n2logV)的一个做法:暴力枚举选哪两个数,然后在对他们的二进制暴力找到x


方法1:01trie

显然看到二进制的题我们首先能想到01trie这个东西

我们把所有的数都加入01trie中,枚举一个数si作为被选择的a,然后看有多少个b满足b<a,然后计算答案即可


方法2: 分治

对于二进制按位贪心的题我们也可以考虑分治。与其说是分治,不如说是一种01trie,但他的特点是没有把树真正的建出来,而是用递归树来代替

我们对于所有的si从高位往低位考虑,对于当前这一位,我们把它分成这一位为01的部分,分别递归计算贡献,在合并的时候这一位为0的显然能对为1的产生贡献

最后再除以总方案数极为要求的答案

posted @   FOX_konata  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
点击右上角即可分享
微信分享提示