CSDN博主:【java_wxid】
CSDN博主:点击【Java廖志伟】
CSDN社区:点击【幕后大佬】
码云:点击【互联网Java工程师知识扫盲】
随笔 - 882,  文章 - 0,  评论 - 1,  阅读 - 51602

分享一道收藏的好题

我收藏的这道题是一道红题,来自洛谷 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,R1] 的情况,这样对于 x + 1 x+1 x+1,它肯定是在 [ L + 1 , R ] [L+1,R] [L+1,R] 中。于是我们可以递归地计算 [ L , R − 1 ] [L,R-1] [L,R1] [ 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=R1 时,我们就不需要递归地计算,直接返回答案即可。

总体而言,这道题的计数方法非常巧妙,值得好好思考和学习。

posted on   我是廖志伟  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

南北踏尘
点击右上角即可分享
微信分享提示