hdu 5661贪心二进制

这题写起来很奇怪所以发个博客以后复习,

题意 是给你两个区间, 让你从中选出两个数,使得他们的异或值最大,1e18的范围,

取得异或值最大肯定要高位越大越好了,一路贪下去

那么分情况讨论,计算在第x位的时候两个数可以取0还是1还是都可以,所以写一个判断函数,(由于都可以不好讨论不妨求出只能是0和只能是1的)

当两个数都是都可以取时候要注意,

这里贪心  将能剩余选择空间更大的取1,显然用上界减去现在的就是剩余空间,(这里我也当时是猜的,一交居然ac了,

放代码,代码巨搓,本蒟蒻还在努力中。。。

#include <iostream>
#include <cstdio>
using namespace std;
long long a,b,c,d;
const long long on=1;
long long x1=0,x2=0;
long long c1,c2;
inline long long pan(long long x,long long a,long long b,int cnt){
    if((x|(on<<cnt))>b)
        return 0;
    if((x|(on<<cnt))<a)
        return 1;
    return 2;
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
        x1=0,x2=0;
        for(int i=60;i>=0;i--){
            c1=pan(x1,a,b,i);
            c2=pan(x2,c,d,i);
            if(c1==2&&c2==2){
                if(b-(x1|on<<i)>d-(x2|on<<i)){
                    x1=(x1|(on<<i));
                }
                else{
                    x2=(x2|(on<<i));
                }
            }
            else if(c1!=2&&c2==2){
                x1=(x1|(c1<<i));
                if(c1==0)
                    c2=1;
                else
                    c2=0;
                x2=(x2|(c2<<i));
            }
            else if(c1==2&&c2!=2){
                x2=(x2|(c2<<i));
                if(c2==0)
                    c1=1;
                else
                    c1=0;
                x1=(x1|(c1<<i));
            }
            else{
                x1=(x1|(c1<<i));
                x2=(x2|(c2<<i));
            }
        }
        printf("%lld
",x1^x2);
    }
    return 0;
}



原文地址:https://www.cnblogs.com/zhangxianlong/p/10672583.html