您的位置:首页 > 其它

hdu 5969 最大的位或(找规律)

2017-08-29 08:49 731 查看
题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5969(前面的博客已经提到了这题,就不贴上原题了,只想说说另外一种思路。)

思路:

如果位或值要最大,首先结果的二进制形式位数得最大,而且高位尽量多1,所以r必须是使得两个数组合位或值最大中的一个,结果的最小值也是r(自身与自身位或结果不变),接下来就是要尽量使得,r二进制形式下中的0尽可能变为1这就要求与之位或的另外一个数此位必须为1,从高位和低位开始遍历都可以,以低位开始遍历为例子,假设r的二进制数为111011,容易知道,与之最接近的并且能使第四位变为1的数为110111,只要判断一下在不在l~r这个范围内就好了,如果不在就可以直接得出答案,不用再向高位考虑了,因为如果低位不满足,说明r与l相差小,而要使得高位的0变为1,则r与l相差的更大,不可能在l~r这个范围内了。

代码:

#include<iostream>
#include<cstring>
using namespace std;
#define LL long long
int bit[65];

LL getsum(int n){
LL sum=1;
for(int i=0; i<n; i++)
sum*=2;
return sum;
}

int main(){
LL l,r,tmp,sum,ans;
int t;
cin>>t;
while(t--){
cin>>l>>r;
tmp=r;
int id=0;
while(tmp){
bit[id++]=tmp&1;
tmp>>=1;
}
sum=0,ans=0;
for(int i=0; i<id; i++){
if(!bit[i]){
if(r-sum-1>=l)
bit[i]=1;
else break;
}
else sum+=getsum(i);
}
for(int i=0; i<id; i++)
ans+=bit[i]*getsum(i);
cout<<ans<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: