首页 > 代码库 > Codechef Xor it (March 12 challenge)
Codechef Xor it (March 12 challenge)
题意很简单,给定N <= 10^5个数,问你两两异或的前k小值。1 ≤ K ≤ min{250000, N*(N-1)/2},a[i] < 2^31
容易想到,要建一个0/1串的trie树,然后考虑每层实际上就是二进制的每一位,然后我们看看ΣC(size,2)是否达到了k,因为这位有ΣC(size,2)对数异或值为0。我们要找的是第一个满足条件的位数,统计前k小即可。实际实现的时候我们可以考虑,把一个数组排个序,其实每段区间就是trie树中的每一层,不需要把trie建出来。二分位数,对每一位计算区间即可。
代码参考了钦爷的代码,感觉吊炸天
Code
#include <bits/stdc++.h> using namespace std; const int N = 100005; int n, k, a[N]; vector<int> ans; int main() { scanf("%d%d", &n, &k); for (int i = 0; i < n; ++i) scanf("%d", &a[i]); sort(a, a + n); int l = -1, r = 31; while (l < r - 1) { int mid = l + r >> 1; long long sum = 0ll; int i, j; for (i = j = 1; i < n; ++i) { if ((a[i] ^ a[i - 1]) < 1 << mid) ++j;//实际是trie else sum += (long long)j * (j - 1) / 2, j = 1; } sum += (long long)j * (j - 1) / 2; if (sum >= k) r = mid; else l = mid; } if (r == 0) for (int i = 0; i < k; ++i) printf("0 "); else { int i, j; for (i = 1, j = 0; i < n; ++i) { if ((a[i] ^ a[i - 1]) < 1 << r) for (int l = j; l < i; ++l) ans.push_back(a[i] ^ a[l]); else j = i; } partial_sort(ans.begin(), ans.begin() + k, ans.end()); for (i = 0; i < k; ++i) printf("%d ", ans[i]); } puts(""); return 0; }
Codechef Xor it (March 12 challenge)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。