题目详情
给定整数区间[a,b],从闭区间[a,b]中选择两个数,使得它们的异或值最大。 0<=a<=b<2^63
这道题还把我给难住了,花了好长时间才分析出一点眉目,大概还是对数学的知觉不够,要加油!!!
//一个复杂算的方法
#include<stdio.h>
typedef long long ll;
ll set(ll v, int top)
{
ll res = 0;
while (top >= 0)
{
res += v << top;
top--;
}
return res;
}
long long maxvalue ( long long a, long long b)
{
ll sum = 0;
int i = 62;
if (a >= b)//处理特例
{
return 0;
}
while (i >= 0 && ((1ll << i) & b) == ((1ll << i) & a))//找最大不同位,在最大不同位之前都是必须异或零的
{
i--;
}
for (;i >= 0; i--)//对每一位进行分情况处理,发现异或总是成立
{
ll ta = ((1ll << i) & a) > 0;
ll tb = ((1ll << i) & b) > 0;
if (ta == 0 && tb == 0)
{
sum += 1ll << i;
a = set(0, i + 1);
}
if (ta == 0 && tb == 1)
{
sum += 1ll << i;
}
if (ta == 1 && tb == 0)
{
sum += 1ll << i;
}
if (ta == 1 && tb == 1)
{
sum += 1ll << i;
b = set(1, i + 1);
}
}
return sum;
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
printf( "%lld" ,100);
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。
typedef long long ll;
ll set(ll v, int top)
{
ll res = 0;
while (top >= 0)
{
res += v << top;
top--;
}
return res;
}
long long maxvalue ( long long a, long long b)
{
ll sum = 0;
int i = 62;
if (a >= b)//处理特例
{
return 0;
}
while (i >= 0 && ((1ll << i) & b) == ((1ll << i) & a))//找最大不同位,在最大不同位之前都是必须异或零的
{
i--;
}
for (;i >= 0; i--)//对每一位进行分情况处理,发现异或总是成立
{
ll ta = ((1ll << i) & a) > 0;
ll tb = ((1ll << i) & b) > 0;
if (ta == 0 && tb == 0)
{
sum += 1ll << i;
a = set(0, i + 1);
}
if (ta == 0 && tb == 1)
{
sum += 1ll << i;
}
if (ta == 1 && tb == 0)
{
sum += 1ll << i;
}
if (ta == 1 && tb == 1)
{
sum += 1ll << i;
b = set(1, i + 1);
}
}
return sum;
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
printf( "%lld" ,100);
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。
//通过上面这个方法可以发现只要找到第一个不同位记下来都是1,故答案如下
#include<stdio.h>
long long maxvalue (long long a,long long b)
{
int i = 62;
if(a >= b)
{
return 0;
}
while(i >= 0 && ((1ll << i) & b) == ((1ll << i) & a))
{
i--;
}
return (1ll << (i + 1)) - 1;
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
printf("%lld",maxvalue(0, ~(1ll << 64 - 1)));
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。
long long maxvalue (long long a,long long b)
{
int i = 62;
if(a >= b)
{
return 0;
}
while(i >= 0 && ((1ll << i) & b) == ((1ll << i) & a))
{
i--;
}
return (1ll << (i + 1)) - 1;
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
printf("%lld",maxvalue(0, ~(1ll << 64 - 1)));
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。