HDU - 5969 最大的位或 (简短)【思维、位运算】

题意:

给出区间 [ L , R ] ,在区间取两个数使它们位或值最大,输出这个最大值。( 0 <= L <= R <= 1e18 )

思路:

我们假设 L = 1001011001 ,R = 1001101010 ;我们可以看到 L 和 R 都有10位并且前四位相同;

然后我们有一种想法:因为 R >= L 所以从左往右数,直到他们有一位不相同(红色部分),那么必有—— R 的这一位为 1 ,L 的这一位必为 0 (因为 R>=L )。

如上面的例子,L和R从左到右到第五位不同,那么有数值:                                                                                                                                                                                                                A = 1001011111                                                                                                                                                                       B = 1001100000

A和B必定在 [ L,  R ] 区间内,而:      A | B = 1001111111   , 所以我们可以知道从红色部分 (L和R从左到右出现不相等的第一位) 开始,后面的位都可以取到 1 前面的位因为都相等,所以不能改变。

同样如果 L = 0001011001 , R = 1001101010 (L 的位数比 R 少)情况也是一样的,就相当于第一位就不相同 ,那么:                                                                                                  A = 0111111111                                                                                                                                                                     B = 1000000000

这两个数也必定在[ L,  R ] 区间内, A | B = 1111111111

代码:

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long Lint;
const Lint one=1;
int t;
int main(){
    Lint l,r;
    cin>>t;
    while(t--){
        scanf("%lld%lld",&l,&r);
        for(int i=62;i>=0;i--){
            Lint t1 = l & (one<<i); // l 的第 i 位(从左到右)
            Lint t2 = r & (one<<i); // r 的第 i 位(从左到右)
            if(t1^t2){
                for(int j=0;j<=i;j++)
                    r=r|(one<<j);  //将 r 后 i 位全部置 1 
                break;
            }
        }
        cout<<r<<endl;
    }
    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值