CodeForces 276D. Little Girl and Maximum XOR(贪心)

题意:给出一段区间,求这个区间内的两个数的异或最大值
解析:
较大的数为a ,小数为b
那么a的二进制格式为1XXXXX…(位数和r一样)
如果011111…>区间最小值
那么这两个数字异或就是最大值
否则
{
b的格式肯定也为1XXXX…
我们令a=r然后枚举a的二进制,
(1)当遇到0时,如果b的相应位置也为0
(2)遇到1 时,
1.如果b的后面位置全为 1满足b>l,那么最大值就是让a 未枚举到的数字都为0 b都为1
2.如果小于l,那么b也为1 ,继续向后枚举
}

#include<bits/stdc++.h>
using namespace  std;
#define ll long long
#define pb push_back
#define inf 2099999999
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i>=b;i--)
const int N=110;
ll arr[N];
ll app[N];
int main()
{
    //freopen("D://rush.txt", "r", stdin);
    ios::sync_with_stdio(false),cin.tie(0);
    ll l,r,a,b,cnt=0,sum1,sum2=0,z=1;
    cin>>l>>r;
    sum1=r;
    a=l,b=r;
    while(b)
    {
        arr[cnt++]=b%2;
        b/=2;
    }
    if((z<<(cnt-1)-1)>=l)
    {
       cout<<(z<<cnt)-1<<endl;
    }
    else
    {
        for(ll i=cnt-1;i>=0;i--)
        {
            if(arr[i]!=0)
            {
                if((sum2+(z<<i)-z)>=l)
                {
                    for(ll j=i-1;j>=0;j--)
                    {
                        if(arr[j]==1)
                        {
                            sum1-=(z<<j);
                        }
                    }
                    sum2+=((z<<i)-z);
                    break;
                }
                else
                {
                    sum2+=(z<<i);
                }
            }
        }
        cout<<(sum1^sum2)<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ffgcc/article/details/81033962