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
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.
number of the test cases.
For each test case, the only line contains four integers a,b,c,d(1≤a,b,c,d≤1018).
Between each two adjacent integers there is a white space separated.
2
1 2 3 4
5 7 13 15
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.
我真也是服了,一个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;
}