BestCoder Round #79 1002/hdu 5661 Claris and XOR 贪心

题目链接

题意:给出四个数a,b,c,d。选择a<=x<=b,c<=y<=d,求x XOR y的最大值。

考虑从高位到低位贪心,对于每一位,如果x,y只有唯一的取法,那么只能这么取;否则贪心地必须使答案的这一位等于1。如果x,y都是0,1都能取,则设这是从右向左数第len位,因为x,y能取的值一定都是连续的一段,因此x,y的后len位都能取0111...1(len-1个1)和1000...0(len-1个0)(否则做不到从右向左数第len位都能取0,1)。也就是说,后len位的贡献一定能达到可能的上界111...1(len个1)。此时不必继续考虑后面的位。

如果x,y在这一位并不是0,1都能取,那么由于要使得答案的这一位等于1,也只有唯一的取法。

至此,这一位考虑完毕,然后根据选取的方案,修正一下x和y的范围,然后对后一位做即可。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long

using namespace std;

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        LL a,b,c,d,ans=0;
        cin>>a>>b>>c>>d;
        for(int i=62;i>=0;i--)
        {
            LL t=(LL)1<<i;
            int x0=0,x1=0,y0=0,y1=0;
            if(b>=t)    x1=1;
            if(d>=t)    y1=1;
            if(t-1>=a)  x0=1;
            if(t-1>=c)  y0=1;
            if(x1&&y1&&x0&&y0)
            {
                ans+=2*t-1;
                break;
            }
            if(x1&&y0)
            {
                ans+=t;
                a-=t;
                b-=t;
                continue;
            }
            if(x0&&y1)
            {
                ans+=t;
                c-=t;
                d-=t;
                continue;
            }
            if(x0==0&&y0==0)
            {
                a-=t;
                b-=t;
                c-=t;
                d-=t;
            }
        }
        cout<<ans<<endl;
    }
}

你可能感兴趣的:(ACM,bc,HDU,贪心,BestCode)