6.24 比赛题解

T1.二进制

问题描述

何老板给你一段区间[L,R],他问你,该区间中,哪一个数字对应的二进制中,“1”的数量最多,请你找出这个数字。

输入格式

第一行,一个整数t,表示何老板一共询问了t次
接下来t行,每行两个整数L,R,表示一次询问区间

输出格式

t行,每行一个整数,依次表示每个询问的答案,如果有多解,输出最小的一个。

数据范围

对于40%的数据:1<=t<=100,0<=L<=R<=105
对于100%的数据:1<=t<=10000,0<=L<=R<=1018

题解:

先找左右界二进制从高位向低位数有多少位是相同的,然后把相同位数的数字记为 p
若找到该处数字不一样,此时的位数为第o位(二进制下),则 a n s = p + 1 << o

代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstring>
#define LL long long 
using namespace std;
int main(){
    LL i,j,l,r,t,p,ans;
    freopen("wei.in","r",stdin);
    freopen("wei.out","w",stdout);
    scanf("%lld",&t);
    while(t--){
        scanf("%lld%lld",&l,&r);
        if(l==r){
            printf("%lld\n",l);
            continue;
        }
        ans=0;
        for(j=63;j>=1;j--){
            p=(1LL<<(j-1));
            if((p&l)!=(p&r))break;
            ans+=p&l;//找相同位数 
        }
        p=(1LL<<j)-1;
        if(p!=(p&r)&&p!=1)
            p=(1LL<<(j-1))-1;//若此时该出后面全是1或者此时位数为1则改变一下p 
        printf("%lld\n",p+ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42013837/article/details/80792039