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 a≤b and c≤d .
He wants to choose two integers x,y that
satisfies a≤x≤b and c≤y≤d ,
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(1≤T≤10,000) ——The
number of the test cases.
For each test case, the only line contains four integersa,b,c,d(1≤a,b,c,d≤1018) .
Between each two adjacent integers there is a white space separated.
For each test case, the only line contains four integers
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 11HintIn 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
我真也是服了,一个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; }