2016年中国大学生程序设计竞赛(合肥)-重现赛1009 HDU 5969

时间:2023-03-08 21:47:25

最大的位或

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

Problem Description
B君和G君聊天的时候想到了如下的问题。
给定自然数l和r ,选取2个整数x,y满足l <= x <= y <= r ,使得x|y最大。
其中|表示按位或,即C、 C++、 Java中的|运算。
Input
包含至多10001组测试数据。
第一行有一个正整数,表示数据的组数。
接下来每一行表示一组数据,包含两个整数l,r。
保证 0 <= l <= r <= 1018

Output
对于每组数据输出一行,表示最大的位或。
Sample Input
5
1 10
0 1
1023 1024
233 322
1000000000000000000
1000000000000000000
Sample Output
15
1
2047
511
1000000000000000000
Source
题意:中文题面
题解:被选择的两个数中,其中的一个数一定是区间的上界,寻找另一个数 初始全部为1 从高位到低位模拟。
 #include<iostream>
#include<cstdio>
#define ll __int64
using namespace std;
ll l,r;
int t;
int s1[];
int s2[];
int s3[];
int len=;
int len1=;
bool cmp1( int * ss,int *tt)
{
for(int i=len-; i>=; i--)
{
if(ss[i]==tt[i])
continue;
if(ss[i]>tt[i])
return true;
if(ss[i]<tt[i])
return false;
}
return true;
}
bool cmp2( int * ss,int *tt)
{
for(int i=len-; i>=; i--)
{
if(ss[i]==tt[i])
continue;
if(ss[i]>tt[i])
return false;
if(ss[i]<tt[i])
return true;
}
return true;
}
void ans()
{
for(int i=len-; i>=; i--)
{
if(s2[i]==||s1[i]==)
s1[i]=;
}
ll exm=;
ll re=;
for(int i=; i<=len-; i++)
{
if(s1[i])
re+=exm;
exm*=;
}
cout<<re<<endl;
}
int main()
{
scanf("%d",&t);
for(int i=; i<=t; i++)
{
int flag=;
len=;
len1=;
scanf("%I64d %I64d",&l,&r);
ll zha=r;
while(r>)
{
if(r&)
s1[len++]=;
else
s1[len++]=;
r>>=;
}
for(int j=; j<len; j++)
{
s2[j]=;
s3[j]=;
}
while(l>)
{
if(l&)
s3[len1++]=;
else
s3[len1++]=;
l>>=;
}
for(int j=len-; j>=; j--)
{
if(s1[j]==)
continue;
if(s1[j]==)
{
s2[j+]=;
if(cmp1(s2,s3)&&cmp2(s2,s1))
{
ans();
flag=;
break;
}
else
{
s2[j+]=s1[j+];
s2[j]=s1[j];
}
}
}
if(flag==)
cout<<zha<<endl;
}
return ;
}