11. 388535

题目链接:388535 (Hard Version)

有一个数组,原先含有 [ l , r ] [l,r] [l,r] 内的整数各一个,现在将它们全都异或上一个 x x x。给出变化后的数组以及 l , r l,r l,r,求 x x x 的值。

这题有一个神奇的做法,但是需要挖掘一些性质。

注意到 ( a ⊕ x ) ⊕ ( b ⊕ x ) = a ⊕ b (a\oplus x)\oplus(b\oplus x)=a\oplus b (ax)(bx)=ab。根据这个性质,对于 [ l , r ] [l,r] [l,r] 中的一对相邻整数 ( 2 k , 2 k + 1 ) (2k,2k+1) (2k,2k+1),它们原来的异或值和变化后的异或值都为 1 1 1,所以我们能够对它们进行匹配。匹配完会出现四种情况:

  • l , r l,r l,r 均为奇数, l ⊕ x l\oplus x lx 无法匹配,与 l l l 异或就得到 x x x
  • l l l 为奇数, r r r 为偶数, l ⊕ x , r ⊕ x l\oplus x,r\oplus x lx,rx 均无法匹配,把两种可能都试一试,暴力检测即可
  • l l l 为偶数, r r r 为奇数,全都可以匹配,说明 x x x 的最后一位可以随便取,钦定这一位为 0 0 0,将所有数右移一位,重复匹配过程
  • l , r l,r l,r 均为偶数, r ⊕ x r\oplus x rx 无法匹配,与 r r r 异或就得到 x x x

这里解释一下为什么第三种情况下最后一位可以随便取:原来范围内的一对整数 ( 2 k , 2 k + 1 ) (2k,2k+1) (2k,2k+1) 的二进制表示形如 A0A1,当 x x x 的二进制形如 B0,即最后一位取 0 0 0 时,异或出来的二进制表示形如 C0C1;当 x x x 的二进制形如 B1,即最后一位取 1 1 1 时,异或出来的二进制表示形如 C1C0。容易发现,这两个结果唯一的差别只是顺序不同,所以是等价的。

#include <bits/stdc++.h>
using namespace std;
int l, r;
set<int> s;
bool check(int x) {
    for (auto it : s) {
        if ((it ^ x) > r || (it ^ x) < l)
            return false;
    }
    return true;
}
void solve() {
    cin >> l >> r;
    s.clear();
    for (int i = l, x; i <= r; i++) {
        cin >> x;
        s.insert(x);
    }
    int ans = 1;
    while (!s.empty()) {
        set<int> t = s;
        for (auto it : s)
            t.erase(it ^ 1);
        if ((l & 1) && (r & 1)) {
            ans *= (*t.begin() ^ l);
            break;
        }
        if ((l & 1) && !(r & 1)) {
            if (check(*t.begin() ^ l))
                ans *= (*t.begin() ^ l);
            else
                ans *= (*t.begin() ^ r);
            break;
        }
        if (!(l & 1) && !(r & 1)) {
            ans *= (*t.begin() ^ r);
            break;
        }
        t.clear();
        for (auto it : s)
            t.insert(it >> 1);
        s = t;
        l >>= 1, r >>= 1, ans <<= 1;
    }
    cout << ans << '\n';
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T = 1;
    cin >> T;
    while (T--) {
        solve();
    }
}

这道题也有 01trie 的做法,同样十分巧妙。将每个数异或上 l l l 就是 x x x 的所有可能值,对于 x x x 的每个可能值都去 trie 上计算最大异或值是否等于 r r r 即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值