1 条题解
-
0
直接说结论和证明:
结论 1:
证明 1:假设 ,那么 ,而且对于 可以覆盖的答案 必定也可以覆盖,而且还可能多覆盖一些数。
结论 2:想象建立一颗 01Trie 维护所有大于 的数。我们的题目相当于找出 条从根的链覆盖尽可能多的节点,每次选择一条最优的链,总覆盖点数就是最大的。
证明 2:简单贪心,显然。
关于代码,我认为我的写法不错:
#include <bits/stdc++.h> using namespace std; int log2_(int k) { int l = 0, r = 62; while (l < r) { if ((1ll << (l + r + 1 >> 1)) > k) r = (l + r + 1 >> 1) - 1; else l = (l + r + 1 >> 1); } return l; } int T, n, k, realk, realn, flag[10000005], cnt; signed main() { cin >> T; while (T--) { cin >> n >> k; if ((1 << (k - 1)) <= n) { for (int i = 0; i < (1 << (k - 1)); i++) cout << (1 << (k - 1)) + i << " "; for (int i = (1 << (k - 1)) + 1; i <= n; i++) cout << "1 "; cout << endl; continue; } cnt = 0; realk = min(k, log2_(n) + 2); realn = (1 << (realk - 1)); for (int i = 0; i < realn; i++) flag[i] = 0; for (int i = (1 << realk); i; i >>= 1) { for (int j = i; j < realn; j += (i << 1)) { if (cnt < n) { cnt++; flag[j] = cnt; cout << ((j + realn) << (k - realk)) << " "; } else { break; } } } cout << endl; } return 0; }
- 1
信息
- ID
- 1232
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者