题意
给定一些数,求这些数中两个数的异或值最大的那个值。
分析
转化成二进制数存入字典树,比如说要查询 \(0011\) ,显然和 \(1100\) 结合最优,所以我们直接在字典树上寻找 \(1100\) ,如果某一位没找到不管它继续往下找,因为我们是从高到低位存的,所以找得到的一定是最优的。
code
#include#include #include typedef long long ll;using namespace std;const int MAXN = 2e6 + 10;int n;int ans;int bit[32];struct Trie { int nxt[MAXN][2]; int root, L; int newnode() { nxt[L][0] = nxt[L][1] = 0; return L++; } void init() { L = 1; root = newnode(); } void insert(int x) { int tmp[32]; memset(tmp, 0, sizeof tmp); int c = 0; while(x) { tmp[c++] = x % 2; x >>= 1; } int now = root; for(int i = 30; i >= 0; i--) { int d = tmp[i]; if(!nxt[now][d]) nxt[now][d] = newnode(); now = nxt[now][d]; } } void query(int x) { int tmp[32]; memset(tmp, 0, sizeof tmp); int c = 0; while(x) { tmp[c++] = !(x % 2); x >>= 1; } for(int i = c; i <= 30; i++) { tmp[i] = 1; } int now = root; int res = 0; for(int i = 30; i >= 0; i--) { int d = tmp[i]; if(nxt[now][d]) res += bit[i]; else d = !d; now = nxt[now][d]; } ans = max(ans, res); }}trie;int main() { bit[0] = 1; for(int i = 1; i < 31; i++) { bit[i] = bit[i - 1] * 2; } while(~scanf("%d", &n)) { trie.init(); ans = 0; for(int i = 0; i < n; i++) { int x; scanf("%d", &x); trie.query(x); trie.insert(x); } printf("%d\n", ans); } return 0;}