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

来源:互联网 发布:电脑怎样连接手机网络 编辑:程序博客网 时间:2024/06/01 13:36

题目链接:
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不能加上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