最大的位或,题解

题目:

    

  样例输入:

    

5

1 10

0 1

1023 1024

233 322

1000000000000000000 1000000000000000000

  样例输出:

15

1

2047

511

1000000000000000000

分析:

   题意很明白,就不再多说,分析一下我们要求的最大,可以这样想,表示成2进制,从高到低,能是1必然是1,即使是1之后会出现许多0也比0优,那么我们就考虑哪一位能是1.

   很显然的贪心,我们考虑一下如何贪心即可。我们想一想这两个数,如果l和r只有前len位一样,那么没办法两个数字必然前len位和l和r一样,那么或出来的数字前len位也和l和r一样,我们考虑len+1位,第len+1一般会是r为1,l为0(除非只有len位),那么我们就可以让一个数前len位和l一样,后面是100。。。这个数字不会比r大,让另一个数前len位也和l一样,后面是011。。。这个数字不会比l小,而这两个数字或之后是前len位后面加上111。。。,显然将会是最优。

  代码:

  

#include <cstdio>
#include <cstring>
const int maxn=64+10;
bool a[maxn];
bool b[maxn];
long long po(int x){
    long long ans=1;
    for(int i=1;i<=x;i++)
        ans*=2ll;
    return ans;
}
int main(){
    int t;
    scanf("%d",&t);
    for(int jsjs=1;jsjs<=t;jsjs++){
        memset(a,0,sizeof(a));
        memset(a,0,sizeof(a));
        long long l,r;
        scanf("%lld%lld",&l,&r);
        int w=1;
        while(l){
            a[w]=l&1;
            l>>=1;
            w++;
        }
        w=1;
        while(r){
            b[w]=r&1;
            r>>=1;
            w++;
        }
        long long ans=0;
        for(int i=w-1;i>=1;i--){
            if(a[i]==b[i]&&a[i])
                ans+=po(i-1);
            else if(a[i]!=b[i]){
                ans+=po(i)-1;
                break;
            }
        }
        printf("%lld
",ans);
    }
    return 0;
} 
原文地址:https://www.cnblogs.com/wish-all-ac/p/12831889.html