Codeforces Round #779 (Div. 2) D2. 388535 (Hard Version)
题目
思路:
求解ans,使ans与 ai 异或后,数组a是[l,r]的一个全排列,由于每个数不同,所以异或后也不会相同,于是直接寻找ai XOR l 最大异或与最小异或,只要他们分别等于l,r。即可证明ai中每一个数都在[l,r]之中,且互不相等,即可得到结果为ai XOR l。寻找最大最大最小异或对,则采用trie异或树来求解
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = (1 << 18) + 10;
const int MAXK = 18;
#define debug printf
typedef long long int lli;
int l, r, a[MAXN], cnt[MAXN];
const int maxn = (1 << 18) + 10 , maxk = 18;
struct triexor{
int trie[2][2 * maxn], N;
void unit(){
for(int i = 0 ;i <= N ; i ++) trie[1][i] = trie[0][i] = 0;
N = 0;
}
void insert(int val)
{
int cur = 0;
for(int k = maxk - 1; k >= 0; k--)
{
bool id = ((val & (1 << k)) > 0);
if(!trie[id][cur]) trie[id][cur] = ++N;
cur = trie[id][cur];
}
}
int maxXor(int val)
{
int cur = 0, xr = 0;
for(int k = maxk - 1; k >= 0; k--)
{
bool id = ((val & (1 << k)) > 0);
if(trie[!id][cur]) cur = trie[!id][cur], xr += (1 << k);
else cur = trie[id][cur];
}
return xr;
}
int minXor(int val)
{
int cur = 0, xr = 0;
for(int k = maxk - 1; k >= 0; k--)
{
bool id = ((val & (1 << k)) > 0);
if(trie[id][cur]) cur = trie[id][cur];
else cur = trie[!id][cur], xr += (1 << k);
}
return xr;
}
}txr;
void solve()
{
int l, r, n;
cin >> l >> r;
n = (r - l + 1);
txr.unit();
for(int i = 1; i <= n; i++)
{
cin >> a[i];
txr.insert(a[i]);
}
for(int i = 1; i <= n; i++)
{
int L = txr.minXor(a[i] ^ l);
int R = txr.maxXor(a[i] ^ l);
//cout<<L<<" "<<R<<endl;
if(l == L && R == r)
{
printf("%d\n", a[i] ^ l);
return;
}
}
}
int main ()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while(t--) solve();
}