HDU-5661 Claris and XOR (贪心)

Claris and XOR

http://acm.hdu.edu.cn/showproblem.php?pid=5661

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


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.

题目大意:给定4个小于等于10^18的数a,b,c,d,又有a<=x<=b,c<=y<=d,求x^y的最大值

昨天只AC了第一题...这样都能涨好多,估计下次div1又得掉好多了

比赛结束后看官方题解没看懂,大脑有点蒙


今天又仔细想了一下,其实从高位开始贪心非常简单,就是有一点绕

对从低位起的第i位考察:

①若x和y第i位取值唯一,则ans与上x,y的第i位的与,x,y的上下限不变

②若x和y第i位有且仅有一个取值唯一,则ans第i为贪心取1,同时变更取值不唯一的数的上下限(例如:若x第i位只能取1,则y第i位贪心取0,同时y的后i-1位上限变为11...11;若x第i位只能取0,则y第i位贪心取1,同时y的后i-1位下限变为00...00)

③若x和y第i为均可以取0和1,则ans后i位均可以贪心得到11...11

(证明:假设x第i位取0,y第i位取1,则x的后i-1位的上限为11...11,y的后i-1位的下限00...00,则x后i-1位可均取11...11,y的后i-1位均取00...00,则ans后i-1位均可得11...11。同理x第i位取1,y第i位取0,ans后i-1位均可得11...11。又ans第i位取1,则ans后i位均可取11...11)


感觉现在屏蔽广告,代码就不高亮了,但是看了几个排名高的博客,屏蔽了没事,是不是无名者就被坑?


#include <cstdio>

using namespace std;

int main() {
    int T;
    long long a,b,c,d,aa,bb,cc,dd,ans;
    scanf("%d",&T);
    while(T-->0) {
        scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&d);
        ans=0;
        for(long long cur=1LL<<61;cur>0;cur>>=1) {
            aa=a&cur;
            bb=b&cur;
            cc=c&cur;
            dd=d&cur;
            if(aa==bb) {//如果x这一位只能取0或1
                if(cc==dd) {//如果y这一位只能取0或1
                    ans|=aa^cc;
                }
                else {//如果y这一位0和1都能取
                    ans|=cur;//ans这一位贪心取1
                    if(aa==0) {//如果x这一位只能取0,则y必定取1
                        c&=cur;//y该位以后的位的下限是00...00
                    }
                    else {//如果x这一位只能取1,则y必定取0
                        d|=cur-1;//y该位以后的位的上限是11...11
                    }
                }
            }
            else {//如果x这一位0和1都能取
                ans|=cur;//ans这一位贪心取1
                if(cc==dd) {//如果y这一位只能取0或1
                    if(cc==0) {//如果y这一位只能取0,则x必定取1
                        a&=cur;
                    }
                    else {//如果y这一位只能取1,则x必定取0
                        b|=cur-1;
                    }
                }
                else {//如果y这一位0和1都能取,任取一个即可,且ans后面所有的位都能取1
                    ans|=cur-1;
                    break;
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


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