HDU 5661 Claris and XOR(贪心)

Claris and XOR

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 874    Accepted Submission(s): 402

Problem Description

Claris loves bitwise operations very much, especially XOR, because it has many beautiful features. He gets four positive integers a,b,c,d that satisfies ab and cd . He wants to choose two integers x,y that satisfies axb and cyd , and maximize the value of x XOR y . But he doesn't know how to do it, so please tell him the maximum value of x XOR y .

Input

The first line contains an integer T(1T10,000) ——The number of the test cases.
For each test case, the only line contains four integers a,b,c,d(1a,b,c,d1018) . Between each two adjacent integers there is a white space separated.

Output

For each test case, the only line contains a integer that is the maximum value of x XOR y .

Sample Input

 
 
2 1 2 3 4 5 7 13 15

Sample Output

 
 
6 11
Hint
In the first test case, when and only when $x=2,y=4$, the value of $x~XOR~y$ is the maximum. In the second test case, when and only when $x=5,y=14$ or $x=6,y=13$, the value of $x~XOR~y$ is the maximum.

Source

BestCoder Round #79 (div.2)



        现在发现了,一般和异或求最值有关的题目都是贪心。这题,还有16年CCPC Final的题等。

        首先,既然是贪心,我们就是得保证,在二进制下,从高到低,每一位都尽量的取1。于是,我们可以根据两个范围分情况讨论。

        对于第i位,如果两对端点的相应位都不一样,即x和y的第i位都是既可以取1也可以取0,那么后面的位就可以不用考虑了,直接全部取1即可。至于为什么,就是说如果x取了下界确定的0,那么对于后面的所有位,相当于可以不用考虑上界了,可以全部取1;而对应y取就要取上界确定的1,这样的话,对于后面所有位,不用考虑下界限制,可以全部取0;如此一来全部0和全部1配对,就是可以保证后面最大可以是全部取1。反之同理。

        然后如果x和y都是只能取0和1当中一个的话,在判断唯一取值是否相同,如果不同,那么说明这一位可以取到1,否则就只能取到0。

        最后是x和y情况不同的时候,即x和y中一个可以取0或1,另一个只能取其中一个。这是我们也是讨论处理。对于有两种选择的数字,如果选取了上界,那么后面就可以不用管下界的限制,直接把下界变为0;如果选取了上界,那么后面可以不用馆上界的限制,直接把上界变为全是1。这个具体道理的话与第一种情况类似。改变了界限之后,不要忘了把答案的这一位变为1。

        如此一位一位的确定就能够组合出最后的最大值,时间复杂度O(logN)。具体见代码::

#include<bits/stdc++.h>
#define LL long long
using namespace std;

int main()
{
    int T,tt=0;
    scanf("%d",&T);
    while (T--)
    {
        bool tag[4]; LL a[4],ans=0;
        scanf("%I64d%I64d%I64d%I64d",&a[0],&a[1],&a[2],&a[3]);
        for(int i=62;i>=0;i--)
        {
            for(int j=0;j<4;j++)
                tag[j]=(1LL<<i)&a[j];						//tag用来记录对应点对应位的取值情况
            if ((tag[0]^tag[1])&&(tag[2]^tag[3]))
            {
                ans|=(1LL<<(i+1))-1; break;					//第一种情况,x和y都是0和1都能取到
            } else if (!(tag[0]^tag[1])&&!(tag[2]^tag[3]))			//第二种情况,x和y都是取值唯一
            {
                if (tag[0]^tag[2]) ans|=(1LL<<i);
            } else if (tag[0]^tag[1])						//第三种情况,二者之一取值唯一,另外一个取值任意
            {
                if (tag[0]^tag[2]) a[1]=(1LL<<i)-1;
                              else a[0]=0;
                ans|=(1LL<<i);
            } else if (tag[2]^tag[3])
            {
                if (tag[1]^tag[2]) a[3]=(1LL<<i)-1;
                              else a[2]=0;
                ans|=(1LL<<i);
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值