Sweety

Practice makes perfect

导航

BC之Claris and XOR

Posted on 2016-04-10 11:11  蓝空  阅读(206)  评论(0编辑  收藏  举报

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

Claris and XOR

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


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
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:  5664 5663 5662 5661 5660 
 


我真也是服了,一个1<<50一样的数据彻底把我打败,从BC的时候,到赛后自己狂敲,然后狂不对,改dfs,超时,依旧不对,我去真也是醉了,看题解思路稍有差别,剪枝,依旧WR

各种测试,我去都不对,然后忽然发现有个1<<num的,应该越界了,改之,不到100毫秒就A掉,直接无语,又被细节打败了。

官方题解:

考虑从高位到低位贪心,对于每一位,如果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的范围,然后对后一位做即可。


细节决定成败。。。


下面是几种思路,既然想了就都粘上吧,都能过。(不多转2进制的函数没用,直接1<<判断就好了。。。)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define MAX 100005
#define INF 0x3f3f3f3f
#define LL long long
#define pii pair<string,int>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
const int dir[][2] = { {-1, 0}, {0, -1}, { 1, 0 }, { 0, 1 } };
using namespace std;
char ch[100];
string  getbia(LL num){
    int i=0;
    string str="",str1;
    while(num){
        if(num%2) str+="1";
        else str+="0";
        num=num>>1;
       // cout<<"OOOOOOO"<<endl;
    }
    int len = str.length();
    for(int i=len-1;i>=0;i--)
        str1+= str[i];
    return str1;
}
int main()
{
    int T;
    LL a ,b,c,d;
    scanf("%d",&T);
    while(T--)
    {
      scanf("%I64d%I64d",&a,&b);
      scanf("%I64d%I64d",&c,&d);
      if(b>d){
        swap(a,c);
        swap(b,d);
      }
      string str1=getbia(d);
      string str2=getbia(b);
      //cout<<str1<<endl;
      int maxLen = str1.length();
      LL res=0;
      for(int i=0;i<=maxLen;i++){
            //cout<<a<<' ' <<b<<' '<<c<<' '<<d<<endl;
        LL temp=(LL)1<<(maxLen-1-i);
        int mark=0;
        if(temp<=d){ ///可以是1
            if(temp-1>=a){
              res+=temp,mark=1;
              d = d>=temp ? d-temp : d;
              c = c>=temp ? c-temp : 0;
              a = a>=temp ? temp-1 : a;
              b = b>=temp ? temp-1 : b;
            }
        }
        if(temp-1>=c&&!mark) { ///可以是0
            if(temp<=b){
              res+=temp,mark;
              d = d>=temp ? temp-1 : d;
              c = c;
              a = a>=temp ? a-temp : a;
              b = b>=temp ? b-temp : 0;
            }
        }
        if(!mark){
          d = d>=temp ? d-temp : d;
          c = c>=temp ? c-temp : c;
          a = a>=temp ? a-temp : a;
          b = b>=temp ? b-temp : b;
        }
        if(a>b) swap(a,b);
        if(c>d) swap(c,d);
        if(b>d){
         swap(a,c);
         swap(b,d);
        }
      }
      printf("%I64d\n",res);
    }
    return 0;
}



#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define MAX 100005
#define INF 0x3f3f3f3f
#define LL long long
#define pii pair<string,int>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
const int dir[][2] = { {-1, 0}, {0, -1}, { 1, 0 }, { 0, 1 } };
using namespace std;
char ch[100];
string  getbia(LL num){
    int i=0;
    string str="",str1;
    while(num){
        if(num%2) str+="1";
        else str+="0";
        num=num>>1;
       // cout<<"OOOOOOO"<<endl;
    }
    int len = str.length();
    for(int i=len-1;i>=0;i--)
        str1+= str[i];
    return str1;
}
//LL tempRes=0;
LL dfs(LL a,LL b,LL c,LL d,int maxLen,LL res){
    LL temp=(LL)1<<(maxLen);
    if(maxLen<0) return res;
    LL a1,b1,c1,d1;
    LL res1=0,res2=0,res3=0,mark=0;


    if((temp<=d&&temp-1>=c) &&(temp-1>=a&&temp<=b)){  ///开始没有这段优化,一直是超时的。。。
        return res+((LL)1<<(maxLen+1))-1;
    }
    if(temp<=d){ ///可以是1
        if(temp-1>=a){
          mark=1;
          d1 = d-temp ;
          c1 = c>=temp ? c-temp : 0;
          a1 = a;
          b1 = b>=temp ? temp-1 : b;
          res1 = dfs(a1,b1,c1,d1,maxLen-1,res+temp);
        }
    }
    if(temp-1>=c&&!mark) { ///可以是0
        if(temp<=b){
          mark=1;
          d1 = d>=temp ? temp-1 : d;
          c1 = c;
          a1 = a>=temp ? a-temp : 0;
          b1 = b-temp;
          res2 = dfs(a1,b1,c1,d1,maxLen-1,res+temp);
        }
    }
    if(!mark){ ///此位异或后不可能为1
       // cout<<"4:";
        a1 = a>=temp ? a-temp : a;
        b1 = b>=temp ? b-temp : b;
        d1 = d>=temp ? d-temp : d;
        c1 = c>=temp ? c-temp : c;
        res3 = dfs(a1,b1,c1,d1,maxLen-1,res);
    }
     LL mmax = max(res1,max(res2,res3)) ;
     return mmax;
}

int main()
{
    int T;
    LL a ,b,c,d;
    scanf("%d",&T);
    while(T--)
    {
      scanf("%I64d%I64d",&a,&b);
      scanf("%I64d%I64d",&c,&d);
      if(b>d){
        swap(a,c);
        swap(b,d);
      }
      string str1=getbia(d);
      string str2=getbia(b);
      int maxLen = str1.length();
      LL res=dfs(a,b,c,d,maxLen-1,0);
      printf("%I64d\n",res);
    }
    return 0;
}



#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define MAX 100005
#define INF 0x3f3f3f3f
#define LL long long
#define pii pair<string,int>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
const int dir[][2] = { {-1, 0}, {0, -1}, { 1, 0 }, { 0, 1 } };
using namespace std;
char ch[100];
string  getbia(LL num){
    int i=0;
    string str="",str1;
    while(num){
        if(num%2) str+="1";
        else str+="0";
        num=num>>1;
       // cout<<"OOOOOOO"<<endl;
    }
    int len = str.length();
    for(int i=len-1;i>=0;i--)
        str1+= str[i];
    return str1;
}
int main()
{
    int T;
    LL a ,b,c,d;
    scanf("%d",&T);
    while(T--)
    {
      scanf("%I64d%I64d",&a,&b);
      scanf("%I64d%I64d",&c,&d);
      if(b>d){
        swap(a,c);
        swap(b,d);
      }
      string str1=getbia(d);
      string str2=getbia(b);
      //cout<<str1<<endl;
      int maxLen = str1.length();
      LL res=0;
      for(int i=0;i<=maxLen;i++){
            //cout<<a<<' ' <<b<<' '<<c<<' '<<d<<endl;
        LL temp=(LL)1<<(maxLen-1-i);
        int mark=0;
        if(temp<=d){ ///可以是1
            if(temp-1>=a){
              res+=temp,mark=1;
              d = d>=temp ? d-temp : d;
              c = c>=temp ? c-temp : 0;
              a = a>=temp ? temp-1 : a;
              b = b>=temp ? temp-1 : b;
            }
        }
        if(temp-1>=c&&!mark) { ///可以是0
            if(temp<=b){
              res+=temp,mark;
              d = d>=temp ? temp-1 : d;
              c = c;
              a = a>=temp ? a-temp : a;
              b = b>=temp ? b-temp : 0;
            }
        }
        if(!mark){
          d = d>=temp ? d-temp : d;
          c = c>=temp ? c-temp : c;
          a = a>=temp ? a-temp : a;
          b = b>=temp ? b-temp : b;
        }
        if(a>b) swap(a,b);
        if(c>d) swap(c,d);
        if(b>d){
         swap(a,c);
         swap(b,d);
        }
      }
      printf("%I64d\n",res);
    }
    return 0;
}