1 条题解
-
0
要维护集合中第 k 大的元素,注意到 k 最大为 10,我们可以用set维护一个集合内前10大的元素 查询时答案就为倒数第 k 个元素,代码如下:
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 2e5 + 10; int fa[N]; set<int> rk[N]; // 维护集合中前 10 大的节点编号 int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } void merge(int x, int y) { int fx = find(x), fy = find(y); if (fx != fy) { fa[fx] = fy; rk[fy].insert(rk[fx].begin(), rk[fx].end()); // 合并 rk[fx].clear(); // 节省空间 while (rk[fy].size() > 10) rk[fy].erase(rk[fy].begin()); // 维护大小保持在 10,删除更小的元素 } } int main() { int n, q; cin >> n >> q; for (int i = 1; i <= n; i++) { fa[i] = i; rk[i].insert(i); } int opt, u, v, k; for (int i = 1; i <= q; i++) { cin >> opt; if (opt == 1) { cin >> u >> v; merge(u, v); } else { cin >> v >> k; int fv = find(v); if (rk[fv].size() < k) cout << "-1\n"; else { auto it = next(rk[fv].rbegin(), k - 1); // 搜索倒数第 k 个元素,即第 k 大的元素 cout << *it << "\n"; } } } return 0; }
- 1
信息
- ID
- 7947
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 3
- 上传者