HDU 5661 Claris and XOR(异或,贪心)

5 篇文章 0 订阅
1 篇文章 0 订阅

题目链接:
HDU 5661 Claris and XOR
题意:
给定区间 [a,b] [c,d] ,求 x[a,b] y[c,d] 使得 xy 的值最大?输出最大的值。
数据范围: ab1018,cd1018
分析:
从后往前贪心。假设当前考虑到第 i 位,令delt=1<<i。我们最好是能让只是 x 加上delt或者只是 y 加上delt。对于每种情况需要考虑加上 delt 之后是否还能属于相应的区间,但是因为还有较低的位上没有考虑,直接考虑合法性的话比较难,可以考虑不合法的情况,也就是最大值比区间左端点小,最小值比区间右端点大。
例如对于 x+delt 如果考虑之后的低位的话,最小值是: Min=x+delt (低位全为0),最大值为: Max=x+delt+delt1 (低位全为1),如果 Min>bMax<a 那么就是不合法的,也就是说 x 不能加上delt,否则 x 可以加上delt
但是我们还要同时考虑 x+delty+delt 能否同时实现,尽管不论能否同时实现两者的异或在这一位上都为0,但是如果不考虑的话,就相当于把 xy 的值缩小了,接下来低位时判断 x+delt 是否属于 [a,b] y+delt 是否属于 [c,d] 会有影响。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long ll;

int T;
ll a, b, c, d;

bool check(ll x, ll y, int pos)
{
    ll extra = ((ll)1 << pos) - 1;
    ll xx = x + extra, yy = y + extra;
    if (x > b || xx < a) return false;
    if (y > d || yy < c) return false;
    return true;
}

int main()
{
    scanf("%d", &T);
    while (T--) {
        scanf("%lld%lld%lld%lld", &a, &b, &c, &d); 
        ll x = 0, y = 0;
        for (int i = 62; i >= 0; --i) {
            ll delt = (ll)1 << i;
            if (check(x + delt, y, i)) x += delt;
            else if (check(x, y + delt, i)) y += delt;
            else if (check(x + delt, y + delt, i)) x += delt, y += delt;
        }
        printf("%lld\n", x ^ y);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值