文章目录
分享一道收藏的好题
我收藏的这道题是一道红题,来自洛谷 P2623,题目名为「计数」。这道题的难度大概在紫到黑的样子,我当初收藏它是因为它是一道奇怪的计数题,有点格雷码的感觉。这道题给定两个整数 a a a 和 b b b,问有多少个 x ∈ [ a , b ] x \in [a,b] x∈[a,b],满足 x ⊕ ( x + 1 ) ∈ [ a , b ] x \oplus (x+1) \in [a,b] x⊕(x+1)∈[a,b],其中 ⊕ \oplus ⊕ 表示按位异或操作。
一开始看到这道题,我一脸懵逼。因为我稍微做过一些计数题,但是好像从没见过按位异或的题。于是我开始思考如何解决这道题。我尝试画图,分析一些规律,但是一直都没能得到正确的答案。
后来我在网上查找资料,看到了一篇题解,介绍了一种非常巧妙的做法。这个做法基于一个性质:如果两个数按位异或后得到的二进制表示中,某一位为 1,则这两个数在这一位上的二进制位一个为 0 一个为 1。这样我们可以对于每一位来统计答案。
具体地,我们可以考虑从高位到低位,类似于二分的操作,不断将区间一分为二。具体地,我们假设当前二进制位为第 k k k 位,我们设 L L L 为 a a a 和 b b b 按照当前位所对应的二进制为止的数,而 R R R 则是 L + 1 L+1 L+1。例如,如果当前位是第 3 位, a a a 的二进制表示为 101110, b b b 的二进制表示为 100011,则 L L L 为 101000,而 R R R 则为 101001。这样,我们就把区间一分为二。
接下来,我们考虑 x ∈ [ L , R − 1 ] x \in [L,R-1] x∈[L,R−1] 的情况,这样对于 x + 1 x+1 x+1,它肯定是在 [ L + 1 , R ] [L+1,R] [L+1,R] 中。于是我们可以递归地计算 [ L , R − 1 ] [L,R-1] [L,R−1] 和 [ L + 1 , R ] [L+1,R] [L+1,R] 中满足条件的 x x x 的个数,然后把两个区间的答案加起来即可。
当然,在具体的计算中,我们还需要考虑一些特殊情况,例如当 L = 0 L=0 L=0 时, x x x 就不能取 0,而当 L = R − 1 L=R-1 L=R−1 时,我们就不需要递归地计算,直接返回答案即可。
总体而言,这道题的计数方法非常巧妙,值得好好思考和学习。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?